我需要使用C++/CLI(数组)将本机(即非托管)数据(byte*)复制到托管字节数组.
我试过Marshal :: Copy(数据由const void*data指向,是dataSize字节)
array<byte>^ _Data=gcnew array<byte>(dataSize);
System::Runtime::InteropServices::Marshal::Copy((byte*)data, _Data, 0, dataSize);
Run Code Online (Sandbox Code Playgroud)
这给出了错误C2665:16个重载中没有一个可以转换所有参数.然后我试了一下
System::Runtime::InteropServices::Marshal::Copy(new IntPtr(data), _Data, 0, dataSize);
Run Code Online (Sandbox Code Playgroud)
产生错误C2664:参数1无法从"const void*"转换为"__w64 int".
那怎么可能呢?Marshal :: Copy确实是"最好的"(最简单/最快)的方式吗?
Ben*_*igt 13
正如您所指出的那样Marshal::Copy(和.NET一般),不是const-safe.
但是,通常的C和C++函数是.你可以写:
array<byte>^ data_array =gcnew array<byte>(dataSize);
pin_ptr<byte> data_array_start = &data_array[0];
memcpy(data_array_start, data, dataSize);
Run Code Online (Sandbox Code Playgroud)
或者避免钉扎:
array<byte>^ data_array =gcnew array<byte>(dataSize);
for( int i = 0; i < data_array->Length; ++i )
data_array[i] = data[i];
Run Code Online (Sandbox Code Playgroud)
Bra*_*etz 12
" IntPtr "只是"void*"的包装.您不应该使用新语法,只需使用显式转换运算符.
System::Runtime::InteropServices::Marshal::Copy( IntPtr( ( void * ) data ), _Data, 0, dataSize );
Run Code Online (Sandbox Code Playgroud)
应该管用.
小智 9
所有这些答案围绕着原始问题中的真正误解而跳舞.所犯的基本错误是这段代码:
System::Runtime::InteropServices::Marshal::Copy(new IntPtr(data),
_Data,
0,
dataSize)
Run Code Online (Sandbox Code Playgroud)
是不正确的..你不是新的(或gcnew)一个IntPtr.它是一种价值类型.其中一个答案显示了这一点,但它没有指出原来的误解.正确的代码可以这样表达:
System::Runtime::InteropServices::Marshal::Copy(IntPtr((void *)data),
_Data,
0,
dataSize)
Run Code Online (Sandbox Code Playgroud)
当我第一次开始使用这些结构时,这让我很困惑.
IntPtr是一个C#struct ..一个值类型.
C++/CLI编译器对此有点迟钝.IntPtr的正式定义是"本机整数",它不是指针类型.但是,C++语言只允许将void*转换为指针类型.CLI支持指针类型,但很少有框架方法接受它们.Marshal :: Copy()没有.三个IntPtr构造函数之一.
你必须使用强制转换或使用IntPtr构造函数来敲击编译器.任何人都猜测这是否仍然适用于128位操作系统,我暂时不会担心它.
| 归档时间: |
|
| 查看次数: |
30964 次 |
| 最近记录: |