如何将 String^ 数组转换为 Void* 数组
How to Convert String^ Array to Void* Array
开发环境:Win32桌面应用程序C++/CLI
让我们有一个这样的数组:
array<String^>^ strArr = gcnew array<String^>(100);
也是这样的数组:
void* ptrArr[100];
我必须将第一个数组的所有元素复制到第二个数组。如何做到这一点?
我假设 void* ptrArr[100]
实际上是 const char* ptrArr[100]
。 void*
实际上可以是任何东西,所以如果不对类型做出假设就无法回答这个问题。
所以,你需要做两件事:你需要在类型之间进行转换(包括从 Unicode 代码点到 ANSI 字符),你需要有一些东西拥有那块内存。
对于 const char*
的非托管内存,有几种选择。最自己动手的路线是 Marshal.StringToHGlobalAnsi
,但这很痛苦,所以我们将跳过它。 (这需要手动跟踪一堆 IntPtr
,并在完成后手动调用 FreeHGlobal
。)
其他选择是 marshal_as
的不同调用。
您可以将所有 String^
个实例转换为 std::string
个实例,并从中提取 const char*
个实例。为此,我推荐 marshal_as<std::string>
。在这种情况下,内存由 std:string
个实例拥有,因此 ptrArr
仅在 stdStrArr
期间有效。
#include <msclr\marshal_cppstd.h>
array<String^>^ strArr = gcnew array<String^>(100);
std::string stdStrArr[100];
const char* ptrArr[100];
for (size_t i = 0; i < 100; i++)
{
stdStrArr[i] = marshal_as<std::string>(strArr[i]);
ptrArr[i] = stdStrArr[i].c_str();
}
// Memory for ptrArr deallocated when stdStrArr goes out of scope.
另一种选择是使用marshal_as
直接转换为const char*
。为此,您分配一个辅助对象。在这种情况下,内存由 marshal_context
实例拥有,因此 ptrArr
仅在 context
有效期间有效。
#include <msclr\marshal.h>
array<String^>^ strArr = gcnew array<String^>(100);
marshal_context^ context = gcnew marshal_context();
char* ptrArr[100];
for (size_t i = 0; i < 100; i++)
{
ptrArr[i] = context->marshal_as<const char*>(strArr[i]);
}
// Memory for ptrArr deallocated when you call `delete context`, or when it's garbage collected.
延伸阅读:
- Overview of Marshaling in C++
marshal_context::marshal_as
(显示使用 marshal_context
的示例)
备注:
- 我没有用编译器检查语法。可能会有小错误。
- 似乎应该有一个问题来将此标记为重复。但是,我找不到 "convert String^ to char*" 评价很高的问题,在答案中使用了
marshal_as
,并展示了如何使用它的一个很好的例子。
开发环境:Win32桌面应用程序C++/CLI
让我们有一个这样的数组:
array<String^>^ strArr = gcnew array<String^>(100);
也是这样的数组:
void* ptrArr[100];
我必须将第一个数组的所有元素复制到第二个数组。如何做到这一点?
我假设 void* ptrArr[100]
实际上是 const char* ptrArr[100]
。 void*
实际上可以是任何东西,所以如果不对类型做出假设就无法回答这个问题。
所以,你需要做两件事:你需要在类型之间进行转换(包括从 Unicode 代码点到 ANSI 字符),你需要有一些东西拥有那块内存。
对于 const char*
的非托管内存,有几种选择。最自己动手的路线是 Marshal.StringToHGlobalAnsi
,但这很痛苦,所以我们将跳过它。 (这需要手动跟踪一堆 IntPtr
,并在完成后手动调用 FreeHGlobal
。)
其他选择是 marshal_as
的不同调用。
您可以将所有 String^
个实例转换为 std::string
个实例,并从中提取 const char*
个实例。为此,我推荐 marshal_as<std::string>
。在这种情况下,内存由 std:string
个实例拥有,因此 ptrArr
仅在 stdStrArr
期间有效。
#include <msclr\marshal_cppstd.h>
array<String^>^ strArr = gcnew array<String^>(100);
std::string stdStrArr[100];
const char* ptrArr[100];
for (size_t i = 0; i < 100; i++)
{
stdStrArr[i] = marshal_as<std::string>(strArr[i]);
ptrArr[i] = stdStrArr[i].c_str();
}
// Memory for ptrArr deallocated when stdStrArr goes out of scope.
另一种选择是使用marshal_as
直接转换为const char*
。为此,您分配一个辅助对象。在这种情况下,内存由 marshal_context
实例拥有,因此 ptrArr
仅在 context
有效期间有效。
#include <msclr\marshal.h>
array<String^>^ strArr = gcnew array<String^>(100);
marshal_context^ context = gcnew marshal_context();
char* ptrArr[100];
for (size_t i = 0; i < 100; i++)
{
ptrArr[i] = context->marshal_as<const char*>(strArr[i]);
}
// Memory for ptrArr deallocated when you call `delete context`, or when it's garbage collected.
延伸阅读:
- Overview of Marshaling in C++
marshal_context::marshal_as
(显示使用marshal_context
的示例)
备注:
- 我没有用编译器检查语法。可能会有小错误。
- 似乎应该有一个问题来将此标记为重复。但是,我找不到 "convert String^ to char*" 评价很高的问题,在答案中使用了
marshal_as
,并展示了如何使用它的一个很好的例子。