You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ec...@apache.org on 2021/06/17 16:37:19 UTC

[geode-native] branch develop updated: GEODE-9358: Initial revision of C bindings (#821)

This is an automated email from the ASF dual-hosted git repository.

echobravo pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-native.git


The following commit(s) were added to refs/heads/develop by this push:
     new d45a0c8  GEODE-9358: Initial revision of C bindings (#821)
d45a0c8 is described below

commit d45a0c827301329fdb0432f011f50dbc2759dc36
Author: Blake Bender <bb...@pivotal.io>
AuthorDate: Thu Jun 17 09:37:08 2021 -0700

    GEODE-9358: Initial revision of C bindings (#821)
    
    Co-authored-by: Blake Bender <bb...@vmware.com>
    Co-authored-by: Matthew Reddington <mr...@pivotal.io>
    Co-authored-by: Michael Oleske <mo...@pivotal.io>
---
 CMakeLists.txt                                     |   1 +
 c_bindings/CMakeLists.txt                          |  63 +++++++++
 c_bindings/include/geode/auth_initialize.h         |  39 ++++++
 c_bindings/include/geode/cache.h                   |  82 +++++++++++
 c_bindings/include/geode/cache/factory.h           |  77 +++++++++++
 c_bindings/include/geode/client.h                  |  41 ++++++
 c_bindings/include/geode/internal/geode_base.h     |  25 ++++
 c_bindings/include/geode/pool.h                    |  38 +++++
 c_bindings/include/geode/pool/factory.h            |  61 ++++++++
 c_bindings/include/geode/pool/manager.h            |  46 ++++++
 c_bindings/include/geode/region.h                  |  61 ++++++++
 c_bindings/include/geode/region/factory.h          |  52 +++++++
 c_bindings/include/geode/region/shortcut.h         |  25 ++++
 .../integration/CMakeLists.txt                     |  33 +----
 c_bindings/integration/test/CAuthInitialize.cpp    | 114 +++++++++++++++
 c_bindings/integration/test/CCacheCreationTest.cpp |  60 ++++++++
 c_bindings/integration/test/CMakeLists.txt         |  72 ++++++++++
 c_bindings/integration/test/ExampleTest.cpp        |  85 ++++++++++++
 .../integration/utilities/CMakeLists.txt           |  35 ++---
 .../integration/utilities/colored_printing.hpp     |  31 +++++
 .../utilities/internal/colored_printing.cpp        |  31 +++++
 .../utilities/internal/colored_printing.hpp        |  45 ++++++
 c_bindings/src/auth_initialize.cpp                 |  73 ++++++++++
 c_bindings/src/auth_initialize.hpp                 |  49 +++++++
 c_bindings/src/cache.cpp                           | 119 ++++++++++++++++
 c_bindings/src/cache.hpp                           |  57 ++++++++
 c_bindings/src/cache/factory.cpp                   | 154 +++++++++++++++++++++
 c_bindings/src/cache/factory.hpp                   |  55 ++++++++
 c_bindings/src/client.cpp                          |  93 +++++++++++++
 c_bindings/src/client.hpp                          |  73 ++++++++++
 c_bindings/src/pool.cpp                            |  41 ++++++
 c_bindings/src/pool.hpp                            |  32 +++++
 c_bindings/src/pool/factory.cpp                    |  67 +++++++++
 c_bindings/src/pool/factory.hpp                    |  39 ++++++
 c_bindings/src/pool/manager.cpp                    |  51 +++++++
 c_bindings/src/pool/manager.hpp                    |  33 +++++
 c_bindings/src/region.cpp                          | 134 ++++++++++++++++++
 c_bindings/src/region.hpp                          |  47 +++++++
 c_bindings/src/region/factory.cpp                  |  68 +++++++++
 c_bindings/src/region/factory.hpp                  |  38 +++++
 c_bindings/symbols                                 |  17 +++
 c_bindings/symbols.version                         |  22 +++
 cmake/ApacheGeodeExportHeader.cmake                |   1 +
 cppcache/include/geode/CacheableString.hpp         |   2 +-
 cppcache/include/geode/DataOutput.hpp              |  14 +-
 cppcache/include/geode/PdxInstanceFactory.hpp      |   4 -
 cppcache/src/PoolManagerImpl.hpp                   |   1 -
 cppcache/src/ThinClientPoolDM.cpp                  |   2 +-
 cppcache/static/CMakeLists.txt                     |   5 +-
 49 files changed, 2338 insertions(+), 70 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fc8350a..8faaaf6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -380,6 +380,7 @@ if (${BUILD_CLI})
   add_subdirectory(templates/security/csharp)
 endif()
 add_subdirectory(tests)
+add_subdirectory(c_bindings)
 
 install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/xsds/ DESTINATION xsds)
 install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/defaultSystem/ DESTINATION defaultSystem)
diff --git a/c_bindings/CMakeLists.txt b/c_bindings/CMakeLists.txt
new file mode 100644
index 0000000..4b3a217
--- /dev/null
+++ b/c_bindings/CMakeLists.txt
@@ -0,0 +1,63 @@
+# 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.
+
+project(apache-geode-c)
+
+add_library(${PROJECT_NAME} SHARED "src/auth_initialize.cpp"
+"src/cache.cpp"
+"src/client.cpp"
+"src/pool.cpp"
+"src/region.cpp"
+"src/cache/factory.cpp"
+"src/pool/factory.cpp"
+"src/pool/manager.cpp"
+"src/region/factory.cpp")
+
+target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
+
+target_link_libraries(${PROJECT_NAME} PRIVATE apache-geode-static)
+
+target_include_directories(${PROJECT_NAME} PRIVATE $<TARGET_PROPERTY:apache-geode-static,SOURCE_DIR>/../src)
+
+include(GenerateExportHeader)
+
+generate_export_header(${PROJECT_NAME}
+  BASE_NAME APACHE_GEODE_C
+  EXPORT_FILE_NAME apache-geode-c_export.h
+  CUSTOM_CONTENT_FROM_VARIABLE EXPORT_HEADER_CUSTOM_CONTENT
+)
+
+include_directories("include" "src" $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  set_target_properties(${PROJECT_NAME} PROPERTIES
+    LINK_FLAGS "-exported_symbols_list \"${CMAKE_CURRENT_SOURCE_DIR}/symbols\"")
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+  set_target_properties(${PROJECT_NAME} PROPERTIES
+    LINK_FLAGS "-Wl,--version-script=\"${CMAKE_CURRENT_SOURCE_DIR}/symbols.version\"")
+endif()
+
+install(TARGETS ${PROJECT_NAME}
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib)
+
+install(DIRECTORY "include/geode/" DESTINATION "c/include/geode")
+
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/apache-geode-c_export.h DESTINATION c/include/geode/internal)
+
+add_subdirectory(integration)
+
+add_clangformat(apache-geode-c)
diff --git a/c_bindings/include/geode/auth_initialize.h b/c_bindings/include/geode/auth_initialize.h
new file mode 100644
index 0000000..c10b1de
--- /dev/null
+++ b/c_bindings/include/geode/auth_initialize.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_AUTH_INITIALIZE_H
+#define APACHE_GEODE_C_AUTH_INITIALIZE_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_properties_s;
+typedef struct apache_geode_properties_s apache_geode_properties_t;
+
+void APACHE_GEODE_C_EXPORT apache_geode_AuthInitialize_AddProperty(
+    apache_geode_properties_t* properties, const char* key, const char* value);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_AUTH_INITIALIZE_H
diff --git a/c_bindings/include/geode/cache.h b/c_bindings/include/geode/cache.h
new file mode 100644
index 0000000..2876a1f
--- /dev/null
+++ b/c_bindings/include/geode/cache.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_CACHE_H
+#define APACHE_GEODE_C_CACHE_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+#include <cstdint>
+#else
+#include <stdint.h>
+#endif
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_cache_s;
+typedef struct apache_geode_cache_s apache_geode_cache_t;
+
+struct apache_geode_pool_manager_s;
+typedef struct apache_geode_pool_manager_s apache_geode_pool_manager_t;
+
+struct apache_geode_region_factory_s;
+typedef struct apache_geode_region_factory_s apache_geode_region_factory_t;
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyCache(apache_geode_cache_t* cache);
+
+APACHE_GEODE_C_EXPORT bool apache_geode_Cache_GetPdxIgnoreUnreadFields(
+    apache_geode_cache_t* cache);
+
+APACHE_GEODE_C_EXPORT bool apache_geode_Cache_GetPdxReadSerialized(
+    apache_geode_cache_t* cache);
+
+APACHE_GEODE_C_EXPORT apache_geode_pool_manager_t*
+apache_geode_Cache_GetPoolManager(apache_geode_cache_t* cache);
+
+#ifdef __cplusplus
+APACHE_GEODE_C_EXPORT apache_geode_region_factory_t*
+apache_geode_Cache_CreateRegionFactory(apache_geode_cache_t* cache,
+                                       std::int32_t regionType);
+#else
+APACHE_GEODE_C_EXPORT apache_geode_region_factory_t*
+apache_geode_Cache_CreateRegionFactory(apache_geode_cache_t* cache,
+                                       int32_t regionType);
+#endif
+
+APACHE_GEODE_C_EXPORT const char* apache_geode_Cache_GetName(
+    apache_geode_cache_t* cache);
+
+APACHE_GEODE_C_EXPORT void apache_geode_Cache_Close(apache_geode_cache_t* cache,
+                                                  bool keepalive);
+
+APACHE_GEODE_C_EXPORT bool apache_geode_Cache_IsClosed(
+    apache_geode_cache_t* cache);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_CACHE_H
diff --git a/c_bindings/include/geode/cache/factory.h b/c_bindings/include/geode/cache/factory.h
new file mode 100644
index 0000000..96a0d9c
--- /dev/null
+++ b/c_bindings/include/geode/cache/factory.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_CACHE_FACTORY_H
+#define APACHE_GEODE_C_CACHE_FACTORY_H
+
+#include "geode/internal/geode_base.h"
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_client_s;
+typedef struct apache_geode_client_s apache_geode_client_t;
+
+struct apache_geode_cache_factory_s;
+typedef struct apache_geode_cache_factory_s apache_geode_cache_factory_t;
+
+struct apache_geode_cache_s;
+typedef struct apache_geode_cache_s apache_geode_cache_t;
+
+struct apache_geode_properties_s;
+typedef struct apache_geode_properties_s apache_geode_properties_t;
+
+APACHE_GEODE_C_EXPORT apache_geode_cache_factory_t*
+apache_geode_CreateCacheFactory();
+
+APACHE_GEODE_C_EXPORT apache_geode_cache_t* apache_geode_CacheFactory_CreateCache(
+    apache_geode_cache_factory_t* factory);
+
+APACHE_GEODE_C_EXPORT const char* apache_geode_CacheFactory_GetVersion(
+    apache_geode_cache_factory_t* factory);
+
+APACHE_GEODE_C_EXPORT const char* apache_geode_CacheFactory_GetProductDescription(
+    apache_geode_cache_factory_t* factory);
+
+APACHE_GEODE_C_EXPORT void apache_geode_CacheFactory_SetPdxIgnoreUnreadFields(
+    apache_geode_cache_factory_t* factory, bool pdxIgnoreUnreadFields);
+
+APACHE_GEODE_C_EXPORT void apache_geode_CacheFactory_SetAuthInitialize(
+    apache_geode_cache_factory_t* factory,
+    void (*getCredentials)(apache_geode_properties_t*), void (*close)());
+
+APACHE_GEODE_C_EXPORT void apache_geode_CacheFactory_SetPdxReadSerialized(
+    apache_geode_cache_factory_t* factory, bool pdxReadSerialized);
+
+APACHE_GEODE_C_EXPORT void apache_geode_CacheFactory_SetProperty(
+    apache_geode_cache_factory_t* factory, const char* key, const char* value);
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyCacheFactory(
+    apache_geode_cache_factory_t* factory);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_CACHE_FACTORY_H
diff --git a/c_bindings/include/geode/client.h b/c_bindings/include/geode/client.h
new file mode 100644
index 0000000..eac1711
--- /dev/null
+++ b/c_bindings/include/geode/client.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_CLIENT_H
+#define APACHE_GEODE_C_CLIENT_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_client_s;
+typedef struct apache_geode_client_s apache_geode_client_t;
+
+APACHE_GEODE_C_EXPORT apache_geode_client_t* apache_geode_ClientInitialize();
+
+APACHE_GEODE_C_EXPORT int apache_geode_ClientUninitialize(
+    apache_geode_client_t* client);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_CLIENT_H
diff --git a/c_bindings/include/geode/internal/geode_base.h b/c_bindings/include/geode/internal/geode_base.h
new file mode 100644
index 0000000..9fd0512
--- /dev/null
+++ b/c_bindings/include/geode/internal/geode_base.h
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_INTERNAL_GEODE_BASE_H
+#define APACHE_GEODE_C_INTERNAL_GEODE_BASE_H
+
+#include "apache-geode-c_export.h"
+
+#endif  // APACHE_GEODE_C_INTERNAL_GEODE_BASE_H
diff --git a/c_bindings/include/geode/pool.h b/c_bindings/include/geode/pool.h
new file mode 100644
index 0000000..30316fb
--- /dev/null
+++ b/c_bindings/include/geode/pool.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_POOL_H
+#define APACHE_GEODE_C_POOL_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_pool_s;
+typedef struct apache_geode_pool_s apache_geode_pool_t;
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyPool(apache_geode_pool_t* pool);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_POOL_H
diff --git a/c_bindings/include/geode/pool/factory.h b/c_bindings/include/geode/pool/factory.h
new file mode 100644
index 0000000..91b0e4b
--- /dev/null
+++ b/c_bindings/include/geode/pool/factory.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_POOL_FACTORY_H
+#define APACHE_GEODE_C_POOL_FACTORY_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+#include <cstdint>
+#else
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_pool_factory_s;
+typedef struct apache_geode_pool_factory_s apache_geode_pool_factory_t;
+
+struct apache_geode_pool_s;
+typedef struct apache_geode_pool_s apache_geode_pool_t;
+
+APACHE_GEODE_C_EXPORT apache_geode_pool_t* apache_geode_PoolFactory_CreatePool(
+    apache_geode_pool_factory_t* poolFactory, const char* name);
+
+#ifdef __cplusplus
+APACHE_GEODE_C_EXPORT void apache_geode_PoolFactory_AddLocator(
+    apache_geode_pool_factory_t* poolFactory, const char* hostname,
+    const std::uint16_t port);
+#else
+APACHE_GEODE_C_EXPORT void apache_geode_PoolFactory_AddLocator(
+    apache_geode_pool_factory_t* poolFactory, const char* hostname,
+    const uint16_t port);
+#endif
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyPoolFactory(
+    apache_geode_pool_factory_t* poolFactory);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_POOL_FACTORY_H
diff --git a/c_bindings/include/geode/pool/manager.h b/c_bindings/include/geode/pool/manager.h
new file mode 100644
index 0000000..d8aa85b
--- /dev/null
+++ b/c_bindings/include/geode/pool/manager.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_POOL_MANAGER_H
+#define APACHE_GEODE_C_POOL_MANAGER_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_pool_manager_s;
+typedef struct apache_geode_pool_manager_s apache_geode_pool_manager_t;
+
+struct apache_geode_pool_factory_s;
+typedef struct apache_geode_pool_factory_s apache_geode_pool_factory_t;
+
+APACHE_GEODE_C_EXPORT apache_geode_pool_factory_t*
+apache_geode_PoolManager_CreateFactory(
+    apache_geode_pool_manager_t* poolManager);
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyPoolManager(
+    apache_geode_pool_manager_t* poolManager);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_POOL_MANAGER_H
diff --git a/c_bindings/include/geode/region.h b/c_bindings/include/geode/region.h
new file mode 100644
index 0000000..7355d04
--- /dev/null
+++ b/c_bindings/include/geode/region.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_REGION_H
+#define APACHE_GEODE_C_REGION_H
+
+#include "geode/internal/geode_base.h"
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_region_s;
+typedef struct apache_geode_region_s apache_geode_region_t;
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyRegion(
+    apache_geode_region_t* region);
+
+APACHE_GEODE_C_EXPORT void apache_geode_Region_PutString(
+    apache_geode_region_t* region, const char* key, const char* value);
+
+APACHE_GEODE_C_EXPORT void apache_geode_Region_PutByteArray(
+    apache_geode_region_t* region, const char* key, const char* value, size_t size);
+
+APACHE_GEODE_C_EXPORT const char* apache_geode_Region_GetString(
+    apache_geode_region_t* region, const char* key);
+
+APACHE_GEODE_C_EXPORT void apache_geode_Region_GetByteArray(
+    apache_geode_region_t* region, const char* key, char** value, size_t* size);
+
+APACHE_GEODE_C_EXPORT void apache_geode_Region_Remove(
+    apache_geode_region_t* region, const char* key);
+
+APACHE_GEODE_C_EXPORT bool apache_geode_Region_ContainsValueForKey(
+    apache_geode_region_t* region, const char* key);
+    
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_REGION_H
diff --git a/c_bindings/include/geode/region/factory.h b/c_bindings/include/geode/region/factory.h
new file mode 100644
index 0000000..9612833
--- /dev/null
+++ b/c_bindings/include/geode/region/factory.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_REGION_FACTORY_H
+#define APACHE_GEODE_C_REGION_FACTORY_H
+
+#include "geode/internal/geode_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+struct apache_geode_cache_s;
+typedef struct apache_geode_cache_s apache_geode_cache_t;
+
+struct apache_geode_region_factory_s;
+typedef struct apache_geode_region_factory_s apache_geode_region_factory_t;
+
+struct apache_geode_region_s;
+typedef struct apache_geode_region_s apache_geode_region_t;
+
+APACHE_GEODE_C_EXPORT void apache_geode_DestroyRegionFactory(
+    apache_geode_region_factory_t* regionFactory);
+
+APACHE_GEODE_C_EXPORT void apache_geode_RegionFactory_SetPoolName(
+    apache_geode_region_factory_t* regionFactory, const char* poolName);
+
+APACHE_GEODE_C_EXPORT apache_geode_region_t*
+apache_geode_RegionFactory_CreateRegion(
+    apache_geode_region_factory_t* regionFactory, const char* regionName);
+
+#ifdef __cplusplus
+}
+#endif  // __cplusplus
+
+#endif  // APACHE_GEODE_C_REGION_FACTORY_H
diff --git a/c_bindings/include/geode/region/shortcut.h b/c_bindings/include/geode/region/shortcut.h
new file mode 100644
index 0000000..e57a84d
--- /dev/null
+++ b/c_bindings/include/geode/region/shortcut.h
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef APACHE_GEODE_C_REGION_SHORTCUT_H
+#define APACHE_GEODE_C_REGION_SHORTCUT_H
+
+enum { PROXY, CACHING_PROXY, CACHING_PROXY_ENTRY_LRU, LOCAL, LOCAL_ENTRY_LRU };
+
+#endif
diff --git a/cmake/ApacheGeodeExportHeader.cmake b/c_bindings/integration/CMakeLists.txt
similarity index 51%
copy from cmake/ApacheGeodeExportHeader.cmake
copy to c_bindings/integration/CMakeLists.txt
index 4dda11a..4abb931 100644
--- a/cmake/ApacheGeodeExportHeader.cmake
+++ b/c_bindings/integration/CMakeLists.txt
@@ -4,39 +4,14 @@
 # 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.
 
-function(generate_export_file LIB_NAME)
-
-  if (MSVC)
-    set(EXPORT_HEADER_CUSTOM_CONTENT "
-  #define APACHE_GEODE_EXPLICIT_TEMPLATE_EXPORT APACHE_GEODE_EXPORT
-
-  #define APACHE_GEODE_EXTERN_TEMPLATE_EXPORT
-  ")
-  else()
-    set(EXPORT_HEADER_CUSTOM_CONTENT "
-  #define APACHE_GEODE_EXPLICIT_TEMPLATE_EXPORT
-
-  #define APACHE_GEODE_EXTERN_TEMPLATE_EXPORT APACHE_GEODE_EXPORT
-  ")
-  endif()
-
-  include(GenerateExportHeader)
-
-  generate_export_header(${PROJECT_NAME}
-    BASE_NAME APACHE_GEODE
-    EXPORT_FILE_NAME apache-geode_export.h
-    CUSTOM_CONTENT_FROM_VARIABLE EXPORT_HEADER_CUSTOM_CONTENT
-  )
-
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/apache-geode_export.h DESTINATION include/geode/internal)
-  
-endfunction()
+add_subdirectory(utilities)
+add_subdirectory(test)
\ No newline at end of file
diff --git a/c_bindings/integration/test/CAuthInitialize.cpp b/c_bindings/integration/test/CAuthInitialize.cpp
new file mode 100644
index 0000000..4c4460d
--- /dev/null
+++ b/c_bindings/integration/test/CAuthInitialize.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#include <framework/Cluster.h>
+#include <framework/Framework.h>
+#include <framework/Gfsh.h>
+
+#include <gtest/gtest.h>
+
+#include "geode/auth_initialize.h"
+#include "geode/cache.h"
+#include "geode/cache/factory.h"
+#include "geode/client.h"
+#include "geode/pool.h"
+#include "geode/pool/factory.h"
+#include "geode/pool/manager.h"
+#include "geode/region.h"
+#include "geode/region/factory.h"
+#include "geode/region/shortcut.h"
+
+static auto credentialsRequested_ = 0;
+
+void simpleGetCredentials(apache_geode_properties_t* props) {
+  apache_geode_AuthInitialize_AddProperty(props, "security-username", "root");
+  apache_geode_AuthInitialize_AddProperty(props, "security-password",
+                                          "root-password");
+  credentialsRequested_++;
+}
+
+void simpleClose() {}
+
+TEST(CAuthInitializeTest, putGetWithBasicAuth) {
+  Cluster cluster(
+      Name(std::string(::testing::UnitTest::GetInstance()
+                           ->current_test_info()
+                           ->test_suite_name()) +
+           "/" +
+           ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+      Classpath{getFrameworkString(FrameworkVariable::JavaObjectJarPath)},
+      SecurityManager{"javaobject.SimpleSecurityManager"}, User{"root"},
+      Password{"root-password"}, LocatorCount{1}, ServerCount{1});
+
+  cluster.start();
+
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("PARTITION")
+      .execute();
+
+  auto client = apache_geode_ClientInitialize();
+  auto cache_factory = apache_geode_CreateCacheFactory();
+
+  apache_geode_CacheFactory_SetProperty(cache_factory,
+                                        "statistic-sampling-enabled", "false");
+  apache_geode_CacheFactory_SetAuthInitialize(
+      cache_factory, simpleGetCredentials, simpleClose);
+
+  auto cache = apache_geode_CacheFactory_CreateCache(cache_factory);
+
+  auto pool_manager = apache_geode_Cache_GetPoolManager(cache);
+  auto pool_factory = apache_geode_PoolManager_CreateFactory(pool_manager);
+
+  for (const auto& locator : cluster.getLocators()) {
+    apache_geode_PoolFactory_AddLocator(pool_factory,
+                                        locator.getAddress().address.c_str(),
+                                        locator.getAddress().port);
+  }
+
+  auto pool = apache_geode_PoolFactory_CreatePool(pool_factory, "default");
+
+  auto region_factory = apache_geode_Cache_CreateRegionFactory(cache, PROXY);
+
+  apache_geode_RegionFactory_SetPoolName(region_factory, "default");
+  auto region =
+      apache_geode_RegionFactory_CreateRegion(region_factory, "region");
+
+  apache_geode_Region_PutString(region, "foo", "bar");
+  apache_geode_Region_PutString(region, "baz", "qux");
+
+  auto foo_value = apache_geode_Region_GetString(region, "foo");
+  ASSERT_STREQ(foo_value, "bar");
+
+  auto baz_value = apache_geode_Region_GetString(region, "baz");
+  ASSERT_STREQ(baz_value, "qux");
+
+  ASSERT_GT(credentialsRequested_, 0);
+
+  apache_geode_DestroyRegion(region);
+  apache_geode_DestroyRegionFactory(region_factory);
+  apache_geode_DestroyPool(pool);
+  apache_geode_DestroyPoolFactory(pool_factory);
+  apache_geode_DestroyPoolManager(pool_manager);
+  apache_geode_DestroyCache(cache);
+
+  apache_geode_DestroyCacheFactory(cache_factory);
+  auto leaks = apache_geode_ClientUninitialize(client);
+  ASSERT_EQ(leaks, 0);
+}
diff --git a/c_bindings/integration/test/CCacheCreationTest.cpp b/c_bindings/integration/test/CCacheCreationTest.cpp
new file mode 100644
index 0000000..37af7d8
--- /dev/null
+++ b/c_bindings/integration/test/CCacheCreationTest.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#include <framework/Cluster.h>
+#include <framework/Framework.h>
+#include <framework/Gfsh.h>
+
+#include <gtest/gtest.h>
+
+#include "geode/cache.h"
+#include "geode/cache/factory.h"
+#include "geode/client.h"
+#include "geode/pool.h"
+#include "geode/pool/factory.h"
+#include "geode/pool/manager.h"
+#include "geode/region.h"
+#include "geode/region/factory.h"
+#include "geode/region/shortcut.h"
+
+/**
+ * Example test using single server and waiting for async put and update
+ * operations to synchronize using promises.
+ */
+TEST(CCacheCreationTest, setPdxIgnoreUnreadFieldsAndCreateCache) {
+  auto client = apache_geode_ClientInitialize();
+  auto cache_factory = apache_geode_CreateCacheFactory();
+
+  apache_geode_CacheFactory_SetProperty(cache_factory,
+                                        "statistic-sampling-enabled", "false");
+
+  apache_geode_CacheFactory_SetPdxIgnoreUnreadFields(cache_factory, true);
+  auto cache = apache_geode_CacheFactory_CreateCache(cache_factory);
+  ASSERT_TRUE(apache_geode_Cache_GetPdxIgnoreUnreadFields(cache));
+
+  apache_geode_CacheFactory_SetPdxIgnoreUnreadFields(cache_factory, false);
+  auto cache2 = apache_geode_CacheFactory_CreateCache(cache_factory);
+  ASSERT_FALSE(apache_geode_Cache_GetPdxIgnoreUnreadFields(cache2));
+
+  apache_geode_DestroyCache(cache);
+  apache_geode_DestroyCache(cache2);
+
+  apache_geode_DestroyCacheFactory(cache_factory);
+  auto leaks = apache_geode_ClientUninitialize(client);
+
+  ASSERT_EQ(leaks, 0);
+}
diff --git a/c_bindings/integration/test/CMakeLists.txt b/c_bindings/integration/test/CMakeLists.txt
new file mode 100644
index 0000000..199c73b
--- /dev/null
+++ b/c_bindings/integration/test/CMakeLists.txt
@@ -0,0 +1,72 @@
+# 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.
+
+project(apache-geode-c-integration-test)
+
+add_executable(${PROJECT_NAME}
+  CAuthInitialize.cpp
+  CCacheCreationTest.cpp
+  ExampleTest.cpp
+)
+
+target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
+
+target_compile_definitions(${PROJECT_NAME}
+  PUBLIC
+    GTEST_ELLIPSIS_NEEDS_POD_
+)
+
+target_include_directories(${PROJECT_NAME}
+  PUBLIC
+   ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC
+    apache-geode-c
+    apache-geode-c-integration-utilities
+    integration-framework
+    testobject
+    ACE::ACE
+    GTest::gtest
+    GTest::gtest_main
+    Boost::boost
+    Boost::system
+    Boost::log
+    Boost::filesystem
+    Boost::chrono
+  PRIVATE
+    _WarningsAsError
+    internal
+)
+
+if(WIN32)
+  foreach (_target apache-geode-c apache-geode testobject)
+    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
+        "$<TARGET_FILE:${_target}>"
+        "$<$<CONFIG:Debug>:$<TARGET_PDB_FILE:${_target}>>"
+        "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
+  endforeach()
+endif()
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
+  FOLDER c_bindings/test/integration
+)
+
+add_clangformat(${PROJECT_NAME})
+
+enable_testing()
+include(GoogleTest)
+gtest_discover_tests(${PROJECT_NAME} DISCOVERY_TIMEOUT 60)
diff --git a/c_bindings/integration/test/ExampleTest.cpp b/c_bindings/integration/test/ExampleTest.cpp
new file mode 100644
index 0000000..9443374
--- /dev/null
+++ b/c_bindings/integration/test/ExampleTest.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#include <framework/Cluster.h>
+#include <framework/Framework.h>
+#include <framework/Gfsh.h>
+
+#include <gtest/gtest.h>
+
+#include "geode/cache.h"
+#include "geode/cache/factory.h"
+#include "geode/client.h"
+#include "geode/pool.h"
+#include "geode/pool/factory.h"
+#include "geode/pool/manager.h"
+#include "geode/region.h"
+#include "geode/region/factory.h"
+#include "geode/region/shortcut.h"
+
+/**
+ * Example test using single server and waiting for async put and update
+ * operations to synchronize using promises.
+ */
+TEST(ExampleTest, putGetAndUpdateWith1Server) {
+  Cluster cluster{LocatorCount{1}, ServerCount{1}};
+
+  cluster.start();
+
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("REPLICATE")
+      .execute();
+
+  auto client = apache_geode_ClientInitialize();
+  auto cache_factory = apache_geode_CreateCacheFactory();
+
+  apache_geode_CacheFactory_SetProperty(cache_factory, "log-level", "none");
+  apache_geode_CacheFactory_SetProperty(cache_factory,
+                                        "statistic-sampling-enabled", "false");
+
+  auto cache = apache_geode_CacheFactory_CreateCache(cache_factory);
+
+  auto pool_manager = apache_geode_Cache_GetPoolManager(cache);
+  auto pool_factory = apache_geode_PoolManager_CreateFactory(pool_manager);
+  apache_geode_PoolFactory_AddLocator(pool_factory, "localhost",
+                                      cluster.getLocatorPort());
+  auto pool = apache_geode_PoolFactory_CreatePool(pool_factory, "myPool");
+  auto region_factory = apache_geode_Cache_CreateRegionFactory(cache, PROXY);
+  apache_geode_RegionFactory_SetPoolName(region_factory, "myPool");
+  auto region =
+      apache_geode_RegionFactory_CreateRegion(region_factory, "region");
+
+  apache_geode_Region_PutString(region, "key", "value");
+
+  auto value = apache_geode_Region_GetString(region, "key");
+
+  ASSERT_STREQ(value, "value");
+
+  apache_geode_DestroyRegion(region);
+  apache_geode_DestroyRegionFactory(region_factory);
+  apache_geode_DestroyPool(pool);
+  apache_geode_DestroyPoolFactory(pool_factory);
+  apache_geode_DestroyPoolManager(pool_manager);
+  apache_geode_DestroyCache(cache);
+  apache_geode_DestroyCacheFactory(cache_factory);
+  auto leaks = apache_geode_ClientUninitialize(client);
+
+  ASSERT_EQ(leaks, 0);
+}
diff --git a/cmake/ApacheGeodeExportHeader.cmake b/c_bindings/integration/utilities/CMakeLists.txt
similarity index 51%
copy from cmake/ApacheGeodeExportHeader.cmake
copy to c_bindings/integration/utilities/CMakeLists.txt
index 4dda11a..a7410c9 100644
--- a/cmake/ApacheGeodeExportHeader.cmake
+++ b/c_bindings/integration/utilities/CMakeLists.txt
@@ -4,39 +4,22 @@
 # 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.
 
-function(generate_export_file LIB_NAME)
+project(apache-geode-c-integration-utilities)
 
-  if (MSVC)
-    set(EXPORT_HEADER_CUSTOM_CONTENT "
-  #define APACHE_GEODE_EXPLICIT_TEMPLATE_EXPORT APACHE_GEODE_EXPORT
+add_library(${PROJECT_NAME} OBJECT "internal/colored_printing.cpp")
 
-  #define APACHE_GEODE_EXTERN_TEMPLATE_EXPORT
-  ")
-  else()
-    set(EXPORT_HEADER_CUSTOM_CONTENT "
-  #define APACHE_GEODE_EXPLICIT_TEMPLATE_EXPORT
+target_link_libraries(${PROJECT_NAME}
+  PUBLIC
+    GTest::gtest
+)
 
-  #define APACHE_GEODE_EXTERN_TEMPLATE_EXPORT APACHE_GEODE_EXPORT
-  ")
-  endif()
-
-  include(GenerateExportHeader)
-
-  generate_export_header(${PROJECT_NAME}
-    BASE_NAME APACHE_GEODE
-    EXPORT_FILE_NAME apache-geode_export.h
-    CUSTOM_CONTENT_FROM_VARIABLE EXPORT_HEADER_CUSTOM_CONTENT
-  )
-
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/apache-geode_export.h DESTINATION include/geode/internal)
-  
-endfunction()
+add_clangformat(apache-geode-c-integration-utilities)
diff --git a/c_bindings/integration/utilities/colored_printing.hpp b/c_bindings/integration/utilities/colored_printing.hpp
new file mode 100644
index 0000000..a1e02cd
--- /dev/null
+++ b/c_bindings/integration/utilities/colored_printing.hpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+#include "utilities/internal/colored_printing.hpp"
+
+namespace util {
+/* Include this header.
+
+   These instances will print that little colored box on the left column, just
+   like GoogleTest does, followed by your formatted text in the color specified.
+   The instances are extern'd to reduce object bloat and compile time. You can
+   find their definition and instantiation in the internal directory below.
+*/
+extern template void print_message<::testing::internal::COLOR_DEFAULT>(const char* fmt...);
+extern template void print_message<::testing::internal::COLOR_GREEN>(const char* fmt...);
+extern template void print_message<::testing::internal::COLOR_YELLOW>(const char* fmt...);
+extern template void print_message<::testing::internal::COLOR_RED>(const char* fmt...);
+}  // namespace util
diff --git a/c_bindings/integration/utilities/internal/colored_printing.cpp b/c_bindings/integration/utilities/internal/colored_printing.cpp
new file mode 100644
index 0000000..aa0a441
--- /dev/null
+++ b/c_bindings/integration/utilities/internal/colored_printing.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+#include "colored_printing.hpp"
+
+namespace util {
+/* This is explicit template instantiation. This translation unit will compile
+   these template instances here, and we can extern them everywhere they are
+   in use to reduce object bloat and compile time.
+ */
+template void print_message<::testing::internal::COLOR_DEFAULT>(
+    const char* fmt...);
+template void print_message<::testing::internal::COLOR_GREEN>(
+    const char* fmt...);
+template void print_message<::testing::internal::COLOR_YELLOW>(
+    const char* fmt...);
+template void print_message<::testing::internal::COLOR_RED>(const char* fmt...);
+}  // namespace util
diff --git a/c_bindings/integration/utilities/internal/colored_printing.hpp b/c_bindings/integration/utilities/internal/colored_printing.hpp
new file mode 100644
index 0000000..5f4ce8f
--- /dev/null
+++ b/c_bindings/integration/utilities/internal/colored_printing.hpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+#include <cstdarg>
+
+#include <gtest/gtest.h>
+
+/* DO NOT INCLUDE THIS HEADER DIRECTLY.
+
+   Use the header of the same name in the directory above. That header contains
+   extern template declarations of these templates to reduce object bloat and
+   compile time.
+*/
+namespace testing {
+  namespace internal {
+    extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
+  }
+}  // namespace testing
+
+namespace util {
+template <::testing::internal::GTestColor color>
+void print_message(const char* fmt...) {
+  va_list args;
+  va_start(args, fmt);
+
+  testing::internal::ColoredPrintf(
+    ::testing::Test::HasFatalFailure() ? testing::internal::COLOR_RED : testing::internal::COLOR_GREEN
+    , "[          ] ");
+
+  testing::internal::ColoredPrintf(color, va_arg(args, char*), args);
+}
+}  // namespace util
diff --git a/c_bindings/src/auth_initialize.cpp b/c_bindings/src/auth_initialize.cpp
new file mode 100644
index 0000000..35b97e2
--- /dev/null
+++ b/c_bindings/src/auth_initialize.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <memory>
+#include <string>
+
+// C++ client public headers
+#include <geode/Properties.hpp>
+
+// C++ client private headers
+#include "util/Log.hpp"
+
+// C client public headers
+#include "geode/auth_initialize.h"
+
+// C client private headers
+#include "auth_initialize.hpp"
+
+void apache_geode_AuthInitialize_AddProperty(
+    apache_geode_properties_t* properties, const char* key, const char* value) {
+  auto securityProperties =
+      reinterpret_cast<apache::geode::client::Properties*>(properties);
+  securityProperties->insert(key, value);
+  LOGDEBUG("AuthInitializeWrapper::%s: added (k, v) = (\"%s\", \"%s\")",
+           __FUNCTION__, key, value);
+}
+
+std::shared_ptr<apache::geode::client::Properties>
+AuthInitializeWrapper::getCredentials(
+    const std::shared_ptr<apache::geode::client::Properties>& securityprops,
+    const std::string& /*server*/) {
+  LOGDEBUG("AuthInitializeWrapper::%s(%p): entry", __FUNCTION__, this);
+
+  if (getCredentials_) {
+    LOGDEBUG("AuthInitializeWrapper::%s(%p): calling getCredentials()",
+             __FUNCTION__, this);
+    getCredentials_(
+        reinterpret_cast<apache_geode_properties_t*>(securityprops.get()));
+  }
+
+  LOGDEBUG("AuthInitializeWrapper::%s(%p): exit", __FUNCTION__, this);
+  return securityprops;
+}
+
+void AuthInitializeWrapper::close() {
+  LOGDEBUG("AuthInitializeWrapper::%s(%p): entry", __FUNCTION__, this);
+
+  if (close_) {
+    LOGDEBUG("AuthInitializeWrapper::%s(%p): calling close()", __FUNCTION__,
+             this);
+    close_();
+  }
+  LOGDEBUG("AuthInitializeWrapper::%s(%p): exit", __FUNCTION__, this);
+}
+
+AuthInitializeWrapper::AuthInitializeWrapper(
+    void (*getCredentials)(apache_geode_properties_t*), void (*close)())
+    : AuthInitialize(), getCredentials_(getCredentials), close_(close) {}
diff --git a/c_bindings/src/auth_initialize.hpp b/c_bindings/src/auth_initialize.hpp
new file mode 100644
index 0000000..e759959
--- /dev/null
+++ b/c_bindings/src/auth_initialize.hpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "geode/AuthInitialize.hpp"
+#include "geode/auth_initialize.h"
+
+namespace apache {
+  namespace geode {
+    namespace client {
+      class Properties;
+    }
+  }
+}
+
+class AuthInitializeWrapper : public apache::geode::client::AuthInitialize {
+  void (*getCredentials_)(apache_geode_properties_t*);
+  void (*close_)();
+
+ public:
+  std::shared_ptr<apache::geode::client::Properties> getCredentials(
+      const std::shared_ptr<apache::geode::client::Properties>& securityprops,
+      const std::string& /*server*/) override;
+
+  void close() override;
+
+  AuthInitializeWrapper(void (*getCredentials)(apache_geode_properties_t*),
+                        void (*close)());
+
+  ~AuthInitializeWrapper() override = default;
+};
diff --git a/c_bindings/src/cache.cpp b/c_bindings/src/cache.cpp
new file mode 100644
index 0000000..ad42cc2
--- /dev/null
+++ b/c_bindings/src/cache.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <cstdint>
+
+// C++ client public headers
+#include "geode/RegionShortcut.hpp"
+
+// C++ client private headers
+#include "util/Log.hpp"
+
+// C client public headers
+#include "geode/cache.h"
+
+// C client private headers
+#include "cache.hpp"
+#include "cache/factory.hpp"
+#include "pool/manager.hpp"
+#include "region/factory.hpp"
+
+void apache_geode_DestroyCache(apache_geode_cache_t* cache) {
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  LOGDEBUG("%s: destroying cache %p", __FUNCTION__, cache);
+  delete cacheWrapper;
+}
+
+bool apache_geode_Cache_GetPdxIgnoreUnreadFields(apache_geode_cache_t* cache) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  return cacheWrapper->getPdxIgnoreUnreadFields();
+}
+
+bool apache_geode_Cache_GetPdxReadSerialized(apache_geode_cache_t* cache) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  return cacheWrapper->getPdxReadSerialized();
+}
+
+apache_geode_pool_manager_t* apache_geode_Cache_GetPoolManager(
+    apache_geode_cache_t* cache) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  return reinterpret_cast<apache_geode_pool_manager_t*>(
+      cacheWrapper->getPoolManager());
+}
+
+apache_geode_region_factory_t* apache_geode_Cache_CreateRegionFactory(
+    apache_geode_cache_t* cache, std::int32_t regionType) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  apache::geode::client::RegionShortcut regionShortcut =
+      static_cast<apache::geode::client::RegionShortcut>(regionType);
+  return reinterpret_cast<apache_geode_region_factory_t*>(
+      cacheWrapper->createRegionFactory(regionShortcut));
+}
+
+const char* apache_geode_Cache_GetName(apache_geode_cache_t* cache) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  return cacheWrapper->getName();
+}
+
+void apache_geode_Cache_Close(apache_geode_cache_t* cache, bool keepalive) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  cacheWrapper->close(keepalive);
+}
+
+bool apache_geode_Cache_IsClosed(apache_geode_cache_t* cache) {
+  LOGDEBUG("%s: cache=%p", __FUNCTION__, cache);
+  CacheWrapper* cacheWrapper = reinterpret_cast<CacheWrapper*>(cache);
+  return cacheWrapper->isClosed();
+}
+
+CacheWrapper::CacheWrapper(apache::geode::client::Cache cache)
+    : cache_(std::move(cache)) {
+  AddRecord(this, "CacheWrapper");
+}
+
+CacheWrapper::~CacheWrapper() { RemoveRecord(this); }
+
+bool CacheWrapper::getPdxIgnoreUnreadFields() {
+  return cache_.getPdxIgnoreUnreadFields();
+}
+
+bool CacheWrapper::getPdxReadSerialized() {
+  return cache_.getPdxReadSerialized();
+}
+
+PoolManagerWrapper* CacheWrapper::getPoolManager() {
+  return new PoolManagerWrapper(this, cache_.getPoolManager());
+}
+
+RegionFactoryWrapper* CacheWrapper::createRegionFactory(
+    apache::geode::client::RegionShortcut regionShortcut) {
+  return new RegionFactoryWrapper(this,
+                                  cache_.createRegionFactory(regionShortcut));
+}
+
+const char* CacheWrapper::getName() { return cache_.getName().c_str(); }
+
+void CacheWrapper::close(bool keepalive) { cache_.close(keepalive); }
+
+bool CacheWrapper::isClosed() { return cache_.isClosed(); }
diff --git a/c_bindings/src/cache.hpp b/c_bindings/src/cache.hpp
new file mode 100644
index 0000000..dc64517
--- /dev/null
+++ b/c_bindings/src/cache.hpp
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "geode/Cache.hpp"
+#include "client.hpp"
+
+
+namespace apache {
+  namespace geode {
+    namespace client {
+      enum class RegionShortcut;
+    }
+  }
+}
+
+class PoolManagerWrapper;
+class RegionFactoryWrapper;
+class CacheFactoryWrapper;
+
+class CacheWrapper: public ClientKeeper {
+  apache::geode::client::Cache cache_;
+
+ public:
+  explicit CacheWrapper(apache::geode::client::Cache);
+  ~CacheWrapper();
+
+  bool getPdxIgnoreUnreadFields();
+
+  bool getPdxReadSerialized();
+
+  PoolManagerWrapper* getPoolManager();
+
+  RegionFactoryWrapper* createRegionFactory(
+      apache::geode::client::RegionShortcut regionShortcut);
+
+  const char* getName();
+
+  void close(bool keepalive);
+
+  bool isClosed();
+};
diff --git a/c_bindings/src/cache/factory.cpp b/c_bindings/src/cache/factory.cpp
new file mode 100644
index 0000000..e0b5bb4
--- /dev/null
+++ b/c_bindings/src/cache/factory.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <iostream>
+#include <memory>
+#include <string>
+
+// C++ client public headers
+#include "geode/CacheFactory.hpp"
+
+// C++ client private headers
+#include "util/Log.hpp"
+
+// C client public headers
+#include "geode/cache.h"
+#include "geode/cache/factory.h"
+#include "geode/client.h"
+
+// C client private headers
+#include "auth_initialize.hpp"
+#include "cache.hpp"
+#include "client.hpp"
+#include "factory.hpp"
+
+CacheFactoryWrapper::CacheFactoryWrapper() {
+  AddRecord(this, "CacheFactoryWrapper");
+  cacheFactory_.set("log-level", "debug");
+  std::cout << __FUNCTION__ << " " << static_cast<void*>(this) << "\n";
+}
+
+CacheFactoryWrapper::~CacheFactoryWrapper() { RemoveRecord(this); }
+
+const char* CacheFactoryWrapper::getVersion() {
+  return cacheFactory_.getVersion().c_str();
+}
+
+const char* CacheFactoryWrapper::getProductDescription() {
+  return cacheFactory_.getProductDescription().c_str();
+}
+
+void CacheFactoryWrapper::setPdxIgnoreUnreadFields(bool pdxIgnoreUnreadFields) {
+  std::cout << __FUNCTION__ << " " << static_cast<void*>(this) << "\n";
+  cacheFactory_.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
+}
+
+void CacheFactoryWrapper::setAuthInitialize(
+    void (*getCredentials)(apache_geode_properties_t*), void (*close)()) {
+  authInit_ = std::make_shared<AuthInitializeWrapper>(getCredentials, close);
+  cacheFactory_.setAuthInitialize(authInit_);
+}
+
+void CacheFactoryWrapper::setPdxReadSerialized(bool pdxReadSerialized) {
+  cacheFactory_.setPdxReadSerialized(pdxReadSerialized);
+}
+
+void CacheFactoryWrapper::setProperty(const std::string& key,
+                                      const std::string& value) {
+  cacheFactory_.set(key, value);
+}
+
+CacheWrapper* CacheFactoryWrapper::createCache() {
+  std::cout << __FUNCTION__ << " " << static_cast<void*>(this) << "\n";
+  return new CacheWrapper(cacheFactory_.create());
+}
+
+apache_geode_cache_factory_t* apache_geode_CreateCacheFactory() {
+  auto factory = new CacheFactoryWrapper();
+  std::cout << __FUNCTION__ << " factory: " << static_cast<void*>(factory)
+            << "\n";
+  LOGDEBUG("%s: factory=%p", __FUNCTION__, factory);
+  return reinterpret_cast<apache_geode_cache_factory_t*>(factory);
+}
+
+apache_geode_cache_t* apache_geode_CacheFactory_CreateCache(
+    apache_geode_cache_factory_t* factory) {
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  CacheWrapper* cache = cacheFactory->createCache();
+  std::cout << __FUNCTION__ << " factory: " << static_cast<void*>(factory)
+            << "cache: " << static_cast<void*>(cache) << "\n";
+  LOGDEBUG("%s: factory=%p, cache=%p", __FUNCTION__, factory, cache);
+  return reinterpret_cast<apache_geode_cache_t*>(cache);
+}
+
+const char* apache_geode_CacheFactory_GetVersion(
+    apache_geode_cache_factory_t* factory) {
+  LOGDEBUG("%s: factory=%p", __FUNCTION__, factory);
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  return cacheFactory->getVersion();
+}
+
+const char* apache_geode_CacheFactory_GetProductDescription(
+    apache_geode_cache_factory_t* factory) {
+  LOGDEBUG("%s: factory=%p", __FUNCTION__, factory);
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  return cacheFactory->getProductDescription();
+}
+
+void apache_geode_CacheFactory_SetPdxIgnoreUnreadFields(
+    apache_geode_cache_factory_t* factory, bool pdxIgnoreUnreadFields) {
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  auto ignoreUnreadFields = pdxIgnoreUnreadFields ? "true" : "false";
+  std::cout << __FUNCTION__ << " factory: " << static_cast<void*>(factory)
+            << "\n";
+  LOGDEBUG("%s: factory=%p, ignoreUnreadFields=%s", __FUNCTION__, factory,
+           ignoreUnreadFields);
+  cacheFactory->setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
+}
+
+void apache_geode_CacheFactory_SetAuthInitialize(
+    apache_geode_cache_factory_t* factory,
+    void (*getCredentials)(apache_geode_properties_t*), void (*close)()) {
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  LOGDEBUG("%s: factory=%p, getCredentials=%p, close=%p", __FUNCTION__, factory,
+           getCredentials, close);
+  cacheFactory->setAuthInitialize(getCredentials, close);
+}
+
+void apache_geode_CacheFactory_SetPdxReadSerialized(
+    apache_geode_cache_factory_t* factory, bool pdxReadSerialized) {
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  auto readSerialized = pdxReadSerialized ? "true" : "false";
+  LOGDEBUG("%s: factory=%p, readSerialized=%s", __FUNCTION__, factory,
+           readSerialized);
+  cacheFactory->setPdxReadSerialized(pdxReadSerialized);
+}
+
+void apache_geode_CacheFactory_SetProperty(
+    apache_geode_cache_factory_t* factory, const char* key, const char* value) {
+  LOGDEBUG("%s: factory=%p, (k, v)=(%s, %s)", __FUNCTION__, factory,
+           std::string(key).c_str(), std::string(value).c_str());
+  auto cacheFactory = reinterpret_cast<CacheFactoryWrapper*>(factory);
+  cacheFactory->setProperty(key, value);
+}
+
+void apache_geode_DestroyCacheFactory(apache_geode_cache_factory_t* factory) {
+  std::cout << __FUNCTION__ << " factory: " << static_cast<void*>(factory)
+            << "\n";
+  delete reinterpret_cast<CacheFactoryWrapper*>(factory);
+}
diff --git a/c_bindings/src/cache/factory.hpp b/c_bindings/src/cache/factory.hpp
new file mode 100644
index 0000000..301c4a8
--- /dev/null
+++ b/c_bindings/src/cache/factory.hpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <memory>
+#include <string>
+
+// C++ client public headers
+#include "geode/CacheFactory.hpp"
+
+// C client public headers
+#include "geode/client.h"
+
+// C client private headers
+#include "auth_initialize.hpp"
+#include "client.hpp"
+
+class CacheFactoryWrapper : public ClientKeeper {
+  apache::geode::client::CacheFactory cacheFactory_;
+  std::shared_ptr<AuthInitializeWrapper> authInit_;
+
+ public:
+  CacheFactoryWrapper();
+
+  ~CacheFactoryWrapper();
+
+  const char* getVersion();
+
+  const char* getProductDescription();
+
+  void setPdxIgnoreUnreadFields(bool pdxIgnoreUnreadFields);
+
+  void setAuthInitialize(void (*getCredentials)(apache_geode_properties_t*),
+                         void (*close)());
+
+  void setPdxReadSerialized(bool pdxReadSerialized);
+
+  void setProperty(const std::string& key, const std::string& value);
+
+  CacheWrapper* createCache();
+};
diff --git a/c_bindings/src/client.cpp b/c_bindings/src/client.cpp
new file mode 100644
index 0000000..59195cb
--- /dev/null
+++ b/c_bindings/src/client.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <iostream>
+#include <string>
+#include <utility>
+
+// C++ client public headers
+#include "geode/Exception.hpp"
+
+// C++ client private headers
+#include "util/Log.hpp"
+
+// C client public headers
+#include "geode/client.h"
+
+// C client private headers
+#include "client.hpp"
+
+std::shared_ptr<ClientWrapper>& PermaClient::instance() {
+  static auto client_ = std::make_shared<ClientWrapper>();
+  return client_;
+}
+
+apache_geode_client_t* apache_geode_ClientInitialize() {
+  return reinterpret_cast<apache_geode_client_t*>(
+      PermaClient::instance().get());
+}
+
+int apache_geode_ClientUninitialize(apache_geode_client_t* client) {
+  try {
+    const int result = PermaClient::instance()->checkForLeaks();
+    return result;
+  } catch (...) {
+    return -1;
+  }
+  return 0;
+}
+
+void Client::AddRecord(void* value, const std::string& className) {
+  do_AddRecord(value, className);
+}
+
+void Client::RemoveRecord(void* value) { do_RemoveRecord(value); }
+
+void ClientKeeper::do_AddRecord(void* value, const std::string& className) {
+  PermaClient::instance()->AddRecord(value, className);
+}
+
+void ClientKeeper::do_RemoveRecord(void* value) {
+  PermaClient::instance()->RemoveRecord(value);
+}
+
+int ClientWrapper::checkForLeaks() {
+  int result = 0;
+  if (!registry_.empty()) {
+    for (auto recordPair : registry_) {
+      auto object = recordPair.first;
+      auto record = recordPair.second;
+
+      LOGERROR("Leaked object of type \"%s\" (pointer value %p), callstack %s",
+               record.className.c_str(), object,
+               record.allocationCallstack.c_str());
+      result = -1;
+    }
+  }
+  return result;
+}
+
+void ClientWrapper::do_AddRecord(void* value, const std::string& className) {
+  using apache::geode::client::Exception;
+
+  registry_.insert({value, {className, Exception("").getStackTrace()}});
+}
+
+void ClientWrapper::do_RemoveRecord(void* value) { registry_.erase(value); }
+
+ClientWrapper::~ClientWrapper() { std::cout << "Geode client shut down...\n"; }
diff --git a/c_bindings/src/client.hpp b/c_bindings/src/client.hpp
new file mode 100644
index 0000000..638e696
--- /dev/null
+++ b/c_bindings/src/client.hpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+#include <memory>
+
+#include "geode/internal/geode_base.h"
+
+// All wrappers are passed their creator object for retention.
+// The parent objects implement this interface.
+class Client {
+  virtual void do_AddRecord(void *, const std::string &) = 0;
+  virtual void do_RemoveRecord(void *) = 0;
+
+ public:
+  // All wrappers call this in their constructors.
+  void AddRecord(void *, const std::string &);
+  // All wrappers call this in their destructors.
+  void RemoveRecord(void *);
+};
+
+// Anything that creates another wrapper derives from this.
+// Adding and removing from this defers to the parent retained within.
+class ClientKeeper : public Client {
+  void do_AddRecord(void *, const std::string &) final override;
+  void do_RemoveRecord(void *) final override;
+};
+
+// This is the top level parent. Adding and removing from any client will
+// ultimately add and remove from an instance of this. This is the client
+// object the user creates from the C interface. Because the wrappers form a
+// hierarchy, it's very important to destroy them in reverse order along that
+// hierarchy.
+class ClientWrapper : public Client {
+  struct ClientObjectRecord {
+    std::string className;
+    std::string allocationCallstack;
+  };
+
+  typedef std::map<void *, ClientObjectRecord> ClientObjectRegistry;
+
+  ClientObjectRegistry registry_;
+
+  void do_AddRecord(void *, const std::string &) final override;
+  void do_RemoveRecord(void *) final override;
+
+ public:
+  int checkForLeaks();
+
+  virtual ~ClientWrapper();
+};
+
+class PermaClient {
+ public:
+    static std::shared_ptr<ClientWrapper> &instance();
+};
\ No newline at end of file
diff --git a/c_bindings/src/pool.cpp b/c_bindings/src/pool.cpp
new file mode 100644
index 0000000..c6fac7a
--- /dev/null
+++ b/c_bindings/src/pool.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <memory>
+
+// C++ public headers
+#include "geode/Pool.hpp"
+
+// C client public headers
+#include "geode/pool.h"
+
+// C client private headers
+#include "pool.hpp"
+#include "pool/factory.hpp"
+
+void apache_geode_DestroyPool(apache_geode_pool_t* pool) {
+  PoolWrapper* poolWrapper = reinterpret_cast<PoolWrapper*>(pool);
+  delete poolWrapper;
+}
+
+PoolWrapper::PoolWrapper(std::shared_ptr<apache::geode::client::Pool> pool)
+    : pool_(pool) {
+  AddRecord(this, "PoolWrapper");
+}
+
+PoolWrapper::~PoolWrapper() { RemoveRecord(this); }
\ No newline at end of file
diff --git a/c_bindings/src/pool.hpp b/c_bindings/src/pool.hpp
new file mode 100644
index 0000000..36b5f8b
--- /dev/null
+++ b/c_bindings/src/pool.hpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include "client.hpp"
+#include "geode/Pool.hpp"
+
+class PoolFactoryWrapper;
+class PoolWrapper : public ClientKeeper {
+  std::shared_ptr<apache::geode::client::Pool> pool_;
+
+ public:
+  explicit PoolWrapper(std::shared_ptr<apache::geode::client::Pool> pool);
+  ~PoolWrapper();
+};
diff --git a/c_bindings/src/pool/factory.cpp b/c_bindings/src/pool/factory.cpp
new file mode 100644
index 0000000..8b4a8a7
--- /dev/null
+++ b/c_bindings/src/pool/factory.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <cstdint>
+#include <string>
+
+// C client public headers
+#include "geode/pool/factory.h"
+
+// C client private headers
+#include "pool.hpp"
+#include "pool/factory.hpp"
+#include "pool/manager.hpp"
+
+apache_geode_pool_t* apache_geode_PoolFactory_CreatePool(
+    apache_geode_pool_factory_t* poolFactory, const char* name) {
+  PoolFactoryWrapper* poolFactoryWrapper =
+      reinterpret_cast<PoolFactoryWrapper*>(poolFactory);
+  return reinterpret_cast<apache_geode_pool_t*>(
+      poolFactoryWrapper->CreatePool(name));
+}
+
+void apache_geode_PoolFactory_AddLocator(
+    apache_geode_pool_factory_t* poolFactory, const char* hostname,
+    const std::uint16_t port) {
+  PoolFactoryWrapper* poolFactoryWrapper =
+      reinterpret_cast<PoolFactoryWrapper*>(poolFactory);
+  poolFactoryWrapper->AddLocator(hostname, port);
+}
+
+void apache_geode_DestroyPoolFactory(apache_geode_pool_factory_t* poolFactory) {
+  PoolFactoryWrapper* poolFactoryWrapper =
+      reinterpret_cast<PoolFactoryWrapper*>(poolFactory);
+  delete poolFactoryWrapper;
+}
+
+PoolFactoryWrapper::PoolFactoryWrapper(
+    apache::geode::client::PoolFactory poolFactory)
+    : poolFactory_(poolFactory) {
+  AddRecord(this, "PoolFactoryWrapper");
+}
+
+PoolFactoryWrapper::~PoolFactoryWrapper() { RemoveRecord(this); }
+
+PoolWrapper* PoolFactoryWrapper::CreatePool(const char* name) {
+  return new PoolWrapper(poolFactory_.create(name));
+}
+
+void PoolFactoryWrapper::AddLocator(const std::string& hostname,
+                                    const std::uint16_t port) {
+  poolFactory_.addLocator(hostname, port);
+}
diff --git a/c_bindings/src/pool/factory.hpp b/c_bindings/src/pool/factory.hpp
new file mode 100644
index 0000000..970af4d
--- /dev/null
+++ b/c_bindings/src/pool/factory.hpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+
+#include "geode/PoolFactory.hpp"
+#include "client.hpp"
+
+class PoolWrapper;
+class PoolManagerWrapper;
+
+class PoolFactoryWrapper: public ClientKeeper {
+  apache::geode::client::PoolFactory poolFactory_;
+
+ public:
+  explicit PoolFactoryWrapper(apache::geode::client::PoolFactory poolFactory);
+  ~PoolFactoryWrapper();
+
+  PoolWrapper* CreatePool(const char* name);
+
+  void AddLocator(const std::string& hostname, std::uint16_t port);
+};
diff --git a/c_bindings/src/pool/manager.cpp b/c_bindings/src/pool/manager.cpp
new file mode 100644
index 0000000..ffe348d
--- /dev/null
+++ b/c_bindings/src/pool/manager.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+// C client public headers
+#include "geode/pool/manager.h"
+
+// C client private headers
+#include "cache.hpp"
+#include "client.hpp"
+#include "pool/factory.hpp"
+#include "pool/manager.hpp"
+
+apache_geode_pool_factory_t* apache_geode_PoolManager_CreateFactory(
+    apache_geode_pool_manager_t* poolManager) {
+  PoolManagerWrapper* poolManagerWrapper =
+      reinterpret_cast<PoolManagerWrapper*>(poolManager);
+  return reinterpret_cast<apache_geode_pool_factory_t*>(
+      poolManagerWrapper->CreatePoolFactory());
+}
+
+void apache_geode_DestroyPoolManager(apache_geode_pool_manager_t* poolManager) {
+  PoolManagerWrapper* poolManagerWrapper =
+      reinterpret_cast<PoolManagerWrapper*>(poolManager);
+  delete poolManagerWrapper;
+}
+
+PoolManagerWrapper::PoolManagerWrapper(
+    CacheWrapper* cache, apache::geode::client::PoolManager& poolManager)
+    : poolManager_(poolManager) {
+  AddRecord(this, "PoolManagerWrapper");
+}
+
+PoolManagerWrapper::~PoolManagerWrapper() { RemoveRecord(this); }
+
+PoolFactoryWrapper* PoolManagerWrapper::CreatePoolFactory() {
+  return new PoolFactoryWrapper(poolManager_.createFactory());
+}
diff --git a/c_bindings/src/pool/manager.hpp b/c_bindings/src/pool/manager.hpp
new file mode 100644
index 0000000..00a351d
--- /dev/null
+++ b/c_bindings/src/pool/manager.hpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "geode/PoolManager.hpp"
+
+class PoolFactoryWrapper;
+class CacheWrapper;
+
+class PoolManagerWrapper: public ClientKeeper {
+  apache::geode::client::PoolManager& poolManager_;
+
+ public:
+  PoolManagerWrapper(CacheWrapper *cache, apache::geode::client::PoolManager& poolManager);
+  ~PoolManagerWrapper();
+
+  PoolFactoryWrapper* CreatePoolFactory();
+};
diff --git a/c_bindings/src/region.cpp b/c_bindings/src/region.cpp
new file mode 100644
index 0000000..500506b
--- /dev/null
+++ b/c_bindings/src/region.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <memory>
+#include <string>
+
+#ifdef _WIN32
+#include <objbase.h>
+#endif  // _WIN32
+
+// C++ client public headers
+#include "geode/CacheableString.hpp"
+#include "geode/Region.hpp"
+#include "geode/RegionShortcut.hpp"
+
+// C client public headers
+#include "geode/region.h"
+#include "geode/region/factory.h"
+
+// C client private headers
+#include "region.hpp"
+#include "region/factory.hpp"
+
+RegionWrapper::RegionWrapper(
+    std::shared_ptr<apache::geode::client::Region> region)
+    : region_(region) {
+  AddRecord(this, "RegionWrapper");
+}
+
+RegionWrapper::~RegionWrapper() { RemoveRecord(this); }
+
+void RegionWrapper::PutString(const std::string& key,
+                              const std::string& value) {
+  region_->put(key, value);
+}
+
+void RegionWrapper::PutByteArray(const std::string& key, const char* value,
+                                 size_t size) {
+  std::vector<int8_t> val(value, value + size);
+  region_->put(key, apache::geode::client::CacheableBytes::create(val));
+}
+
+const char* RegionWrapper::GetString(const std::string& key) {
+  auto value = region_->get(key);
+  lastValue_ =
+      std::dynamic_pointer_cast<apache::geode::client::CacheableString>(value)
+          ->value();
+  return lastValue_.c_str();
+}
+
+void RegionWrapper::GetByteArray(const std::string& key, char** value,
+                                 size_t* size) {
+  std::shared_ptr<apache::geode::client::Serializable> val = region_->get(key);
+
+  if (val.get() == nullptr) return;
+
+  auto bytes =
+      std::dynamic_pointer_cast<apache::geode::client::CacheableBytes>(val);
+  int valSize = val->objectSize();
+#if defined(_WIN32)
+  int8_t* byteArray = static_cast<int8_t*>(CoTaskMemAlloc(valSize));
+#else
+  int8_t* byteArray = static_cast<int8_t*>(malloc(valSize));
+#endif
+  if (bytes) {
+    memcpy(byteArray, bytes->value().data(), valSize);
+    *value = reinterpret_cast<char*>(byteArray);
+    *size = valSize;
+  }
+}
+
+void RegionWrapper::Remove(const std::string& key) { region_->remove(key); }
+
+bool RegionWrapper::ContainsValueForKey(const std::string& key) {
+  return region_->containsValueForKey(key);
+}
+
+void apache_geode_DestroyRegion(apache_geode_region_t* region) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  delete regionWrapper;
+}
+
+void apache_geode_Region_PutString(apache_geode_region_t* region,
+                                   const char* key, const char* value) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  regionWrapper->PutString(key, value);
+}
+
+void apache_geode_Region_PutByteArray(apache_geode_region_t* region,
+                                      const char* key, const char* value,
+                                      size_t size) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  regionWrapper->PutByteArray(key, value, size);
+}
+
+const char* apache_geode_Region_GetString(apache_geode_region_t* region,
+                                          const char* key) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  return regionWrapper->GetString(key);
+}
+
+void apache_geode_Region_GetByteArray(apache_geode_region_t* region,
+                                      const char* key, char** value,
+                                      size_t* size) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  return regionWrapper->GetByteArray(key, value, size);
+}
+
+void apache_geode_Region_Remove(apache_geode_region_t* region,
+                                const char* key) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  return regionWrapper->Remove(key);
+}
+
+bool apache_geode_Region_ContainsValueForKey(apache_geode_region_t* region,
+                                             const char* key) {
+  RegionWrapper* regionWrapper = reinterpret_cast<RegionWrapper*>(region);
+  return regionWrapper->ContainsValueForKey(key);
+}
diff --git a/c_bindings/src/region.hpp b/c_bindings/src/region.hpp
new file mode 100644
index 0000000..603a2c7
--- /dev/null
+++ b/c_bindings/src/region.hpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+#include <memory>
+
+#include "client.hpp"
+#include "geode/Region.hpp"
+
+class RegionFactoryWrapper;
+
+class RegionWrapper : public ClientKeeper {
+  std::shared_ptr<apache::geode::client::Region> region_;
+  std::string lastValue_;
+
+ public:
+  explicit RegionWrapper(std::shared_ptr<apache::geode::client::Region> region);
+  ~RegionWrapper();
+
+  void PutString(const std::string& key, const std::string& value);
+
+  void PutByteArray(const std::string& key, const char* value, size_t size);
+
+  const char* GetString(const std::string& key);
+
+  void GetByteArray(const std::string& key, char** value, size_t* size);
+
+  void Remove(const std::string& key);
+
+  bool ContainsValueForKey(const std::string& key);
+};
diff --git a/c_bindings/src/region/factory.cpp b/c_bindings/src/region/factory.cpp
new file mode 100644
index 0000000..f5ff13f
--- /dev/null
+++ b/c_bindings/src/region/factory.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+// Standard headers
+#include <string>
+#include <utility>
+
+// C++ client public headers
+#include "geode/RegionFactory.hpp"
+
+// C client public headers
+#include "geode/region.h"
+#include "geode/region/factory.h"
+
+// C client private headers
+#include "cache.hpp"
+#include "region.hpp"
+#include "region/factory.hpp"
+
+RegionFactoryWrapper::RegionFactoryWrapper(
+    CacheWrapper* cache, apache::geode::client::RegionFactory regionFactory)
+    : regionFactory_(std::move(regionFactory)) {
+  AddRecord(this, "RegionFactoryWrapper");
+}
+
+RegionFactoryWrapper::~RegionFactoryWrapper() { RemoveRecord(this); }
+
+void RegionFactoryWrapper::setPoolName(const std::string& poolName) {
+  regionFactory_.setPoolName(poolName);
+}
+
+RegionWrapper* RegionFactoryWrapper::createRegion(
+    const std::string& regionName) {
+  return new RegionWrapper(regionFactory_.create(regionName));
+}
+
+void apache_geode_DestroyRegionFactory(
+    apache_geode_region_factory_t* regionFactory) {
+  delete reinterpret_cast<RegionFactoryWrapper*>(regionFactory);
+}
+
+void apache_geode_RegionFactory_SetPoolName(
+    apache_geode_region_factory_t* regionFactory, const char* poolName) {
+  RegionFactoryWrapper* regionFactoryWrapper =
+      reinterpret_cast<RegionFactoryWrapper*>(regionFactory);
+  regionFactoryWrapper->setPoolName(poolName);
+}
+apache_geode_region_t* apache_geode_RegionFactory_CreateRegion(
+    apache_geode_region_factory_t* regionFactory, const char* regionName) {
+  RegionFactoryWrapper* regionFactoryWrapper =
+      reinterpret_cast<RegionFactoryWrapper*>(regionFactory);
+  return reinterpret_cast<apache_geode_region_t*>(
+      regionFactoryWrapper->createRegion(regionName));
+}
diff --git a/c_bindings/src/region/factory.hpp b/c_bindings/src/region/factory.hpp
new file mode 100644
index 0000000..ded2243
--- /dev/null
+++ b/c_bindings/src/region/factory.hpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "geode/RegionFactory.hpp"
+#include "client.hpp"
+
+class RegionWrapper;
+class CacheWrapper;
+
+class RegionFactoryWrapper: public ClientKeeper {
+  apache::geode::client::RegionFactory regionFactory_;
+
+ public:
+  RegionFactoryWrapper(CacheWrapper *, apache::geode::client::RegionFactory regionFactory);
+  ~RegionFactoryWrapper();
+
+  void setPoolName(const std::string& poolName);
+
+  RegionWrapper* createRegion(const std::string& regionName);
+};
diff --git a/c_bindings/symbols b/c_bindings/symbols
new file mode 100644
index 0000000..0f15796
--- /dev/null
+++ b/c_bindings/symbols
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+apache_geode_*
\ No newline at end of file
diff --git a/c_bindings/symbols.version b/c_bindings/symbols.version
new file mode 100644
index 0000000..42ad881
--- /dev/null
+++ b/c_bindings/symbols.version
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+V0 {
+  global:
+    apache_geode_*;
+  local:
+    *;
+};
\ No newline at end of file
diff --git a/cmake/ApacheGeodeExportHeader.cmake b/cmake/ApacheGeodeExportHeader.cmake
index 4dda11a..2f887f3 100644
--- a/cmake/ApacheGeodeExportHeader.cmake
+++ b/cmake/ApacheGeodeExportHeader.cmake
@@ -40,3 +40,4 @@ function(generate_export_file LIB_NAME)
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/apache-geode_export.h DESTINATION include/geode/internal)
   
 endfunction()
+
diff --git a/cppcache/include/geode/CacheableString.hpp b/cppcache/include/geode/CacheableString.hpp
index 91a651c..bc01884 100644
--- a/cppcache/include/geode/CacheableString.hpp
+++ b/cppcache/include/geode/CacheableString.hpp
@@ -54,7 +54,7 @@ class APACHE_GEODE_EXPORT CacheableString
       : m_str(std::move(value)), m_hashcode(0) {
     bool ascii = isAscii(m_str);
 
-    m_type = m_str.length() > std::numeric_limits<uint16_t>::max()
+    m_type = m_str.length() > (std::numeric_limits<uint16_t>::max)()
                  ? ascii ? DSCode::CacheableASCIIStringHuge
                          : DSCode::CacheableStringHuge
              : ascii ? DSCode::CacheableASCIIString
diff --git a/cppcache/include/geode/DataOutput.hpp b/cppcache/include/geode/DataOutput.hpp
index eeb9abd..73e6873 100644
--- a/cppcache/include/geode/DataOutput.hpp
+++ b/cppcache/include/geode/DataOutput.hpp
@@ -274,7 +274,7 @@ class APACHE_GEODE_EXPORT DataOutput {
   inline void writeString(const std::basic_string<_CharT, _Tail...>& value) {
     // without scanning string, making worst case choices.
     // TODO constexp for each string type to jmutf8 length conversion
-    if (value.length() * 3 <= std::numeric_limits<uint16_t>::max()) {
+    if (value.length() * 3 <= (std::numeric_limits<uint16_t>::max)()) {
       write(static_cast<uint8_t>(DSCode::CacheableString));
       writeJavaModifiedUtf8(value);
     } else {
@@ -516,8 +516,8 @@ class APACHE_GEODE_EXPORT DataOutput {
   Pool* m_pool;
 
   inline void writeAscii(const std::string& value) {
-    uint16_t len = static_cast<uint16_t>(
-        std::min<size_t>(value.length(), std::numeric_limits<uint16_t>::max()));
+    uint16_t len = static_cast<uint16_t>(std::min<size_t>(
+        value.length(), (std::numeric_limits<uint16_t>::max)()));
     writeInt(len);
     for (size_t i = 0; i < len; i++) {
       // blindly assumes ascii so mask off only 7 bits
@@ -526,8 +526,8 @@ class APACHE_GEODE_EXPORT DataOutput {
   }
 
   inline void writeAsciiHuge(const std::string& value) {
-    uint32_t len = static_cast<uint32_t>(
-        std::min<size_t>(value.length(), std::numeric_limits<uint32_t>::max()));
+    uint32_t len = static_cast<uint32_t>(std::min<size_t>(
+        value.length(), (std::numeric_limits<uint32_t>::max)()));
     writeInt(static_cast<uint32_t>(len));
     for (size_t i = 0; i < len; i++) {
       // blindly assumes ascii so mask off only 7 bits
@@ -566,7 +566,7 @@ class APACHE_GEODE_EXPORT DataOutput {
     } else {
       auto encodedLen = static_cast<uint16_t>(
           std::min<size_t>(getJavaModifiedUtf8EncodedLength(data, len),
-                           std::numeric_limits<uint16_t>::max()));
+                           (std::numeric_limits<uint16_t>::max)()));
       writeInt(encodedLen);
       ensureCapacity(encodedLen);
       const auto end = m_buf + encodedLen;
@@ -606,7 +606,7 @@ class APACHE_GEODE_EXPORT DataOutput {
 
   inline void writeUtf16Huge(const char16_t* data, size_t length) {
     uint32_t len = static_cast<uint32_t>(
-        std::min<size_t>(length, std::numeric_limits<uint32_t>::max()));
+        std::min<size_t>(length, (std::numeric_limits<uint32_t>::max)()));
     writeInt(len);
     writeUtf16(data, length);
   }
diff --git a/cppcache/include/geode/PdxInstanceFactory.hpp b/cppcache/include/geode/PdxInstanceFactory.hpp
index 7f93117..76b0038 100644
--- a/cppcache/include/geode/PdxInstanceFactory.hpp
+++ b/cppcache/include/geode/PdxInstanceFactory.hpp
@@ -53,10 +53,6 @@ class APACHE_GEODE_EXPORT PdxInstanceFactory {
  public:
   PdxInstanceFactory() = delete;
   ~PdxInstanceFactory() noexcept = default;
-  PdxInstanceFactory(const PdxInstanceFactory& other) = default;
-  PdxInstanceFactory& operator=(const PdxInstanceFactory& other) = default;
-  PdxInstanceFactory(PdxInstanceFactory&& other) = default;
-  PdxInstanceFactory& operator=(PdxInstanceFactory&& other) = default;
 
  public:
   /**
diff --git a/cppcache/src/PoolManagerImpl.hpp b/cppcache/src/PoolManagerImpl.hpp
index a35eae0..763267e 100644
--- a/cppcache/src/PoolManagerImpl.hpp
+++ b/cppcache/src/PoolManagerImpl.hpp
@@ -40,7 +40,6 @@ class PoolFactory;
 class PoolManagerImpl {
  public:
   explicit PoolManagerImpl(CacheImpl* cache) : m_cache(cache) {}
-  PoolManagerImpl(const PoolManagerImpl& copy) = default;
   ~PoolManagerImpl() = default;
 
   void removePool(const std::string& name);
diff --git a/cppcache/src/ThinClientPoolDM.cpp b/cppcache/src/ThinClientPoolDM.cpp
index 696b41a..e46d487 100644
--- a/cppcache/src/ThinClientPoolDM.cpp
+++ b/cppcache/src/ThinClientPoolDM.cpp
@@ -1189,7 +1189,7 @@ TcrEndpoint* ThinClientPoolDM::getEndPoint(
 
 std::shared_ptr<TcrEndpoint> ThinClientPoolDM::getEndpoint(
     const std::string& endpointName) {
-  m_endpoints.make_lock();
+  const auto& ignored = m_endpoints.make_lock();
   const auto& find = m_endpoints.find(endpointName);
   if (find == m_endpoints.end()) {
     return {};
diff --git a/cppcache/static/CMakeLists.txt b/cppcache/static/CMakeLists.txt
index 6a63a94..9bd40ba 100644
--- a/cppcache/static/CMakeLists.txt
+++ b/cppcache/static/CMakeLists.txt
@@ -52,7 +52,10 @@ if (MSVC)
   )
 endif()
 
-set_target_properties(apache-geode-static PROPERTIES INTERPROCEDURAL_OPTIMIZATION FALSE)
+set_target_properties(apache-geode-static PROPERTIES 
+  INTERPROCEDURAL_OPTIMIZATION FALSE
+  POSITION_INDEPENDENT_CODE ON
+)
 
 # BEGIN Visual Studio organization
 source_group("Header Files" REGULAR_EXPRESSION "\.(hpp|inl)$")