You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by jb...@apache.org on 2021/07/08 18:56:16 UTC

[geode-native] branch develop updated: GEODE-9412: Fixes translation of String between .NET and C++ (#829)

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

jbarrett 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 b8fdb0f  GEODE-9412: Fixes translation of String between .NET and C++ (#829)
b8fdb0f is described below

commit b8fdb0f7044cb78ba11898c2d0a3dbbc04f60cf0
Author: Jacob Barrett <ja...@vmware.com>
AuthorDate: Thu Jul 8 11:56:07 2021 -0700

    GEODE-9412: Fixes translation of String between .NET and C++ (#829)
    
    Adds new String.hpp similar to C++ client's string.hpp.
    Converts String to std::string via UTF-16 to UTF-8 transform.
    Converts std::string to String via UTF-8 to UTF-16 transform.
    Adds basic unit tests for String.hpp methods.
    
    Adds basic unit tests for Serializable.
    
    Splits the .NET library into objects and assembly so that unit tests
    can link directly against the objects to avoid symbol export issues
    crossing C++/CLI layers.
    
    Fixes ACE PDB location so it can be correctly included in dependent projects.
---
 clicache/src/CMakeLists.txt         | 54 ++++++++++++++++++++++++-------------
 clicache/src/Serializable.cpp       |  7 ++---
 clicache/src/String.hpp             | 54 +++++++++++++++++++++++++++++++++++++
 clicache/test/CMakeLists.txt        | 23 +++++++---------
 clicache/test/SerializableTests.cpp | 49 +++++++++++++++++++++++++++++++++
 clicache/test/StringTests.cpp       | 45 +++++++++++++++++++++++++++++++
 dependencies/ACE/CMakeLists.txt     |  1 +
 7 files changed, 198 insertions(+), 35 deletions(-)

diff --git a/clicache/src/CMakeLists.txt b/clicache/src/CMakeLists.txt
index ab5f454..16503f5 100644
--- a/clicache/src/CMakeLists.txt
+++ b/clicache/src/CMakeLists.txt
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.12)
 project(Apache.Geode CXX)
 
 if(NOT "${STRONG_NAME_PUBLIC_KEY}" STREQUAL "")
@@ -23,8 +23,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/impl/AssemblyInfo.cpp.in ${CMAKE_CURR
 list(APPEND CONFIGURE_IN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/impl/AssemblyInfo.cpp.in)
 list(APPEND CONFIGURE_OUT_FILES ${CMAKE_CURRENT_BINARY_DIR}/impl/AssemblyInfo.cpp)
 
-add_library(Apache.Geode SHARED
-  Apache.Geode.rc
+add_library(Apache.Geode-object OBJECT
   AttributesMutator.cpp
   AttributesMutator.hpp
   begin_native.hpp
@@ -194,6 +193,7 @@ add_library(Apache.Geode SHARED
   Struct.hpp
   StructSet.cpp
   StructSet.hpp
+  String.hpp
   SystemProperties.cpp
   SystemProperties.hpp
   TimeUtils.hpp
@@ -210,7 +210,6 @@ add_library(Apache.Geode SHARED
   Utils.hpp
   impl/AppDomainContext.cpp
   impl/AppDomainContext.hpp
-  impl/AssemblyInfo.cpp.in
   impl/AuthenticatedView.cpp
   impl/AuthenticatedView.hpp
   impl/CacheListener.hpp
@@ -298,23 +297,20 @@ add_library(Apache.Geode SHARED
   impl/TransactionListener.hpp
   impl/TransactionWriter.hpp
   impl/WeakhashMap.hpp
-
-  ${CONFIGURE_OUT_FILES}
 )
 
-set_target_properties(Apache.Geode PROPERTIES
-  COMMON_LANGUAGE_RUNTIME "" 
-  OUTPUT_NAME ${PRODUCT_DLL_NAME}
+set_target_properties(Apache.Geode-object PROPERTIES
+  COMMON_LANGUAGE_RUNTIME ""
   VS_GLOBAL_CLRSupport "true"
   VS_GLOBAL_KEYWORD "ManagedCProj"
   VS_GLOBAL_PROJECT_TYPES "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
-  VS_GLOBAL_ROOTNAMESPACE ${PROJECT_NAME}
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode
   VS_DOTNET_REFERENCES "System;System.Xml;System.Core"
   FOLDER cli
 )
 
-target_compile_options(Apache.Geode
-  PRIVATE
+target_compile_options(Apache.Geode-object
+  PUBLIC
 	/bigobj # C1128 - large number of templates causes too many section.
 	/Zm32   # C3859 - internal heap limit reached
 	#/doc # Documents to xml
@@ -324,21 +320,43 @@ target_compile_options(Apache.Geode
 	/wd4947 /wd4251 /wd4635
 )
 
-target_include_directories(Apache.Geode
+target_include_directories(Apache.Geode-object
   PRIVATE
   	$<TARGET_PROPERTY:apache-geode,SOURCE_DIR>/../src
 )
 
-target_link_libraries(Apache.Geode
+target_link_libraries(Apache.Geode-object
   PUBLIC
-    psapi
-  PRIVATE
     c++cli
     c++11
     apache-geode-static
 	_WarningsAsError
 )
 
+add_library(Apache.Geode SHARED
+  Apache.Geode.rc
+  ${CONFIGURE_IN_FILES}
+  ${CONFIGURE_OUT_FILES}
+)
+
+set_target_properties(Apache.Geode PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "" 
+  OUTPUT_NAME ${PRODUCT_DLL_NAME}
+  VS_GLOBAL_CLRSupport "true"
+  VS_GLOBAL_KEYWORD "ManagedCProj"
+  VS_GLOBAL_PROJECT_TYPES "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Core"
+  FOLDER cli
+)
+
+target_link_libraries(Apache.Geode
+  PUBLIC
+    psapi
+  PRIVATE
+	Apache.Geode-object
+)
+
 target_link_options(Apache.Geode
   PRIVATE
     /DELAYLOAD:libssl-1_1-x64.dll
@@ -351,7 +369,7 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SHARED_LINKER_FLAG
 
 
 include(PrecompiledHeader)
-add_precompiled_header(Apache.Geode geode_includes.hpp FORCEINCLUDE)
+add_precompiled_header(Apache.Geode-object geode_includes.hpp FORCEINCLUDE)
 
 install(TARGETS Apache.Geode
   RUNTIME DESTINATION bin
@@ -359,7 +377,7 @@ install(TARGETS Apache.Geode
 )
 
 install ( 
-  FILES $<TARGET_PDB_FILE:${PROJECT_NAME}> 
+  FILES $<TARGET_PDB_FILE:Apache.Geode> 
   DESTINATION bin 
   CONFIGURATIONS Debug RelWithDebInfo 
 )
diff --git a/clicache/src/Serializable.cpp b/clicache/src/Serializable.cpp
index 34a222f..cc49f04 100644
--- a/clicache/src/Serializable.cpp
+++ b/clicache/src/Serializable.cpp
@@ -47,6 +47,7 @@
 #include "impl/DotNetTypes.hpp"
 #include "CacheRegionHelper.hpp"
 #include "Cache.hpp"
+#include "String.hpp"
 
 #pragma warning(disable:4091)
 
@@ -387,17 +388,17 @@ namespace Apache
       {
         if (auto cacheableString = std::dynamic_pointer_cast<native::CacheableString>(nativeptr))
         {
-          return marshal_as<String^>(cacheableString->value());
+          return to_String(cacheableString->value());
         }
 
-        return marshal_as<String^>(nativeptr->toString());
+        return to_String(nativeptr->toString());
       }
 
       std::shared_ptr<native::CacheableString> Serializable::GetCacheableString(String^ value)
       {
         std::shared_ptr<native::CacheableString> cStr;
         if (value) {
-          cStr = native::CacheableString::create(marshal_as<std::string>(value));
+          cStr = native::CacheableString::create(to_utf8(value));
         }
         else {
           cStr = std::dynamic_pointer_cast<native::CacheableString>(native::CacheableString::createDeserializable());
diff --git a/clicache/src/String.hpp b/clicache/src/String.hpp
new file mode 100644
index 0000000..a18024a
--- /dev/null
+++ b/clicache/src/String.hpp
@@ -0,0 +1,54 @@
+/*
+ * 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 <codecvt>
+
+#include <msclr/marshal.h>
+#include <msclr/marshal_cppstd.h>
+
+using namespace System;
+
+namespace Apache
+{
+  namespace Geode
+  {
+    namespace Client
+    {
+
+      inline std::string to_utf8(const std::wstring& utf16) {
+        return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}.to_bytes(utf16);
+      }
+
+      inline std::string to_utf8(String^ utf16) {
+        return to_utf8(msclr::interop::marshal_as<std::wstring>(utf16));
+      }
+
+      inline std::wstring to_wstring(const std::string& utf8) {
+        return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}.from_bytes(utf8);
+      }
+
+      inline String^ to_String(const std::string& utf8) {
+        return msclr::interop::marshal_as<String^>(to_wstring(utf8));
+      }
+
+    }  // namespace Client
+  }  // namespace Geode
+}  // namespace Apache
+
diff --git a/clicache/test/CMakeLists.txt b/clicache/test/CMakeLists.txt
index a47f10d..898a117 100644
--- a/clicache/test/CMakeLists.txt
+++ b/clicache/test/CMakeLists.txt
@@ -13,28 +13,28 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.12)
 project(Apache.Geode.Test CXX)
 
 set(vstest_dir ${CMAKE_BINARY_DIR}/packages/Microsoft.TestPlatform.16.8.3/tools/net451/Common7/IDE/Extensions/TestPlatform)
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages.config ${CMAKE_CURRENT_BINARY_DIR}/packages.config COPYONLY)
+list(APPEND CONFIGURE_IN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/packages.config)
+list(APPEND CONFIGURE_OUT_FILES ${CMAKE_CURRENT_BINARY_DIR}/packages.config)
 
-if(NOT "${STRONG_NAME_PUBLIC_KEY}" STREQUAL "")
-  set(STRONG_NAME_PUBLIC_KEY_ATTRIBUTE ", PublicKey=${STRONG_NAME_PUBLIC_KEY}")
-endif()
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AssemblyInfo.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/AssemblyInfo.cpp)
 list(APPEND CONFIGURE_IN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/AssemblyInfo.cpp.in)
 list(APPEND CONFIGURE_OUT_FILES ${CMAKE_CURRENT_BINARY_DIR}/AssemblyInfo.cpp)
 
 add_library(Apache.Geode.Test MODULE
-  AssemblyInfo.cpp.in
   native_conditional_unqiue_ptrTests.cpp
   native_shared_ptrTests.cpp
   native_unique_ptrTests.cpp
   TimeUtilsTests.cpp
+  SerializableTests.cpp
+  StringTests.cpp
+  ${CONFIGURE_IN_FILES}
   ${CONFIGURE_OUT_FILES}
-  packages.config
 )
 
 set_target_properties(Apache.Geode.Test PROPERTIES
@@ -52,27 +52,22 @@ set_target_properties(Apache.Geode.Test PROPERTIES
 
 target_include_directories(Apache.Geode.Test
   PRIVATE
-  	$<TARGET_PROPERTY:apache-geode,SOURCE_DIR>
+  	$<TARGET_PROPERTY:apache-geode,SOURCE_DIR>/../src
   	$<TARGET_PROPERTY:apache-geode,INCLUDE_DIRECTORIES>
-  	$<TARGET_PROPERTY:Apache.Geode,SOURCE_DIR>
+  	$<TARGET_PROPERTY:Apache.Geode-object,SOURCE_DIR>
 )
 
 target_link_libraries(Apache.Geode.Test
   PUBLIC
-    # Apache.Geode #- Causes include of .lib
+    Apache.Geode-object
   PRIVATE
     c++cli
 	c++11
 	_WarningsAsError
 )
 
-# Makes project only reference, no .lib.
-add_dependencies(Apache.Geode.Test Apache.Geode)
 add_dependencies(Apache.Geode.Test nuget-restore)
 
-string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
-set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${SHARED_LINKER_FLAGS_STRONG_KEY}")
-
 # For Visual Studio organization
 source_group("Configure In Files" FILES ${CONFIGURE_IN_FILES})
 source_group("Configure Out Files" FILES ${CONFIGURE_OUT_FILES})
diff --git a/clicache/test/SerializableTests.cpp b/clicache/test/SerializableTests.cpp
new file mode 100644
index 0000000..c4eddd1
--- /dev/null
+++ b/clicache/test/SerializableTests.cpp
@@ -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.
+ */
+
+#include "Serializable.hpp"
+#include <geode/CacheableString.hpp>
+
+using namespace System;
+using namespace System::Text;
+using namespace System::Collections::Generic;
+using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
+
+using Apache::Geode::Client::Serializable;
+
+[TestClass]
+public ref class SerializableTests
+{
+public: 
+
+  [TestMethod]
+  void GetCacheableStringHandlesNonAsciiCharacters()
+  {
+    auto cacheableString = Serializable::GetCacheableString(gcnew String(L"foo\u2019s\U00010003"));
+    Assert::IsFalse(cacheableString.get() == nullptr);
+    Assert::IsTrue(std::string("foo\xE2\x80\x99s\xf0\x90\x80\x83") == cacheableString->value());
+  }
+
+    [TestMethod]
+  void GetStringHandlesNonAsciiCharacters()
+  {
+    auto cacheableString = apache::geode::client::CacheableString::create("foo\xE2\x80\x99s\xf0\x90\x80\x83");
+    auto str = Serializable::getString(cacheableString);
+    Assert::AreEqual(gcnew String(L"foo\u2019s\U00010003"), str);
+  }
+
+};
diff --git a/clicache/test/StringTests.cpp b/clicache/test/StringTests.cpp
new file mode 100644
index 0000000..bef1349
--- /dev/null
+++ b/clicache/test/StringTests.cpp
@@ -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 "String.hpp"
+
+using namespace System;
+using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
+using namespace Apache::Geode::Client;
+
+[TestClass]
+public ref class StringTests
+{
+public: 
+
+  [TestMethod]
+  void to_uft8FromStringHandlesNonAscii()
+  {
+    String^ str = L"foo\u2019s\U00010003";
+    auto utf8 = to_utf8(str);
+    Assert::IsTrue(std::string("foo\xE2\x80\x99s\xf0\x90\x80\x83") == utf8);
+  }
+
+  
+  [TestMethod]
+  void to_StringFromUtf8HandlesNonAscii()
+  {
+    std::string utf8("foo\xE2\x80\x99s\xf0\x90\x80\x83");
+    auto str = to_String(utf8);
+    Assert::AreEqual(gcnew String(L"foo\u2019s\U00010003"), str);
+  }
+};
diff --git a/dependencies/ACE/CMakeLists.txt b/dependencies/ACE/CMakeLists.txt
index d8c12e1..dd546e3 100644
--- a/dependencies/ACE/CMakeLists.txt
+++ b/dependencies/ACE/CMakeLists.txt
@@ -89,6 +89,7 @@ if (${WIN32})
   )
   set ( _INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/lib <INSTALL_DIR>/lib
                  COMMAND ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/ace <INSTALL_DIR>/include/ace
+                 COMMAND ${CMAKE_COMMAND} -E copy <SOURCE_DIR>/ace/Static_$<$<CONFIG:Debug>:Debug>$<$<NOT:$<CONFIG:Debug>>:Release>/ace_${MPC_TYPE}_static/AMD64/ACE_${MPC_TYPE}_static.pdb <INSTALL_DIR>/lib
   )
 
   set(CMAKE_STATIC_LIBRARY_SUFFIX s$<${MSVC}:$<$<CONFIG:Debug>:d>>.lib)