---
title: Getting Started with the Native Library
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

To use the <%=vars.product_name%> Native Library for developing <%=vars.product_name%> client applications:

- Obtain a distribution of the Native library and install it on your development platform.
- Set up your development environment with the tools you need, such as a compiler and an OpenSSL security library.
- Establish access to a new or existing <%=vars.product_name%> cluster.
- Write your client application using the <%=vars.product_name%> native library to interact with the <%=vars.product_name%> server.

## <a id="set_up_dev_environment"></a>Set Up Your Development Environment

You will need some essential tools, such as a compiler and a linker.
Your compiler must have access to the Native Client header files, and the linker must have access to the Native Client libraries.
The header files and libraries are located in the Native Client installation directory.

## <a id="establish_cluster_access"></a>Establish Access to a <%=vars.product_name%> Cluster

As you develop your application, you will need access to a <%=vars.product_name%> cluster.
Your client application connects to a <%=vars.product_name%> cluster by specifying the address (host name
or IP address) and port number of one or more locators, and the name of a region that also exists
on the cluster.
The client API establishes a pool of these network connections for your client application to use.

You can choose whether to use a large, remote, production-quality cluster; a small, local,
development cluster; or something in-between, such as a testing or experimental lab installation.

In the _<%=vars.product_name%> User's Guide_,
see [Configuring and Running a Cluster](<%=vars.serverman%>/configuring/chapter_overview.html) 
and [Client/Server Configuration](<%=vars.serverman%>/topologies_and_comm/cs_configuration/chapter_overview.html) for instructions on setting up and starting the cluster for a client/server configuration.

### <a id="connecting_to_server"></a>Connecting to the Server

To connect to a server, your application must follow these steps:

1. Create a cache, setting characteristics of interest (for example, `log-level`).
1. Use the cache to create a named pool of network connections, specifying the hostname and port for at least one server locator.
1. Instantiate a region of the desired type (usually PROXY, sometimes CACHING_PROXY) and connect it by name to its counterpart on the server.

Once the connection pool and the shared region are in place, your client application is ready to share data with the server.

**Server Connection: C++ Example**

Create a cache and set its characteristics:

``` cpp
auto cache = CacheFactory()
    .set("log-level", "debug")
    .set("ssl-enabled", "true")
    .set("ssl-truststore", clientTruststore.string())
    .create();
```

Use the cache to create a named pool of network connections, specifying the hostname and port for the server locator:


``` cpp
cache.getPoolManager()
      .createFactory()
      .addLocator("localhost", 10334)
      .create("pool");
```

Instantiate a region of the desired type and connect to the pool by name::

``` cpp
auto regionFactory = cache.createRegionFactory(RegionShortcut::PROXY);
auto region = regionFactory.setPoolName("pool").create("exampleRegion");
```

See the _<%=vars.product_name%> User Guide_ section [Configuring a Client/Server System](<%=vars.serverman%>/topologies_and_comm/cs_configuration/setting_up_a_client_server_system.html)
for more details.

### <a id="app_dev_walkthroughs"></a>Application Development Walkthrough

The [C++ App Development Walkthrough](app-dev-walkthrough-cpp.html) describes how to set up a native client development environment using CMake.

## <a id="programming_examples"></a>Programming Examples

The <%=vars.product_name%> Client build provides a set of programming examples to help you understand the client API.
The `examples` directory contains CMake files and a `cpp` subdirectory containing C++ examples.
The Windows build also includes a `dotnet` subdirectory containing C# examples.

CMake files are located at each level of the directory structure to allow examples to be built individually or in groups.

The directory structure resembles this hierarchy (some entries are omitted for clarity):

```
MyProject/
  cmake/
  CMakeLists.txt
  examples/
    BUILD-EXAMPLES.md
    CMakeLists.txt
    CMakeLists.txt.in
    cmake/
    cpp/
      authinitialize/
      continuousquery/
      dataserializable/
      functionexecution/
      pdxserializable/
      pdxserializer/
      putgetremove/
      remotequery/
      sslputget/
      transaction/
    dotnet/
      authinitialize/
      continuousquery/
      dataserializable/
      functionexecution/
      pdxautoserializer/
      pdxserializable/
      putgetremove/
      remotequery/
      sslputget/
      transaction/
```

See the `BUILD-EXAMPLES.md` file for detailed instructions on building and executing the examples,
and read the source code to understand how the examples are constructed.

See [Put/Get/Remove Example](put-get-example.html) for sample code showing the basics of how a client application
connects to a <%=vars.product_name%> cluster and performs basic operations on a remote server.
