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)