如何将String ^ Array转换为Void * Array

问题描述 投票:0回答:1

开发环境:Win32桌面应用程序C ++ / CLI

我们有一个像这样的数组:

array<String^>^ strArr = gcnew array<String^>(100);

像这样的数组:

void* ptrArr[100];

我必须将所有第一个数组的元素复制到第二个数组。这该怎么做?

arrays type-conversion c++-cli
1个回答
1
投票

我假设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. 

进一步阅读:

笔记:

  • 我没有用编译器检查我的语法。可能存在小错误。
  • 似乎应该有一个问题来标记这个重复。但是,我无法找到高度评价的“转换字符串^到字符*”问题,在答案中使用了marshal_as,并展示了如何使用它的一个很好的例子。
© www.soinside.com 2019 - 2024. All rights reserved.