Copy unmanaged data into managed array

前端 未结 5 945
广开言路
广开言路 2020-12-28 17:13

I need to copy native (i.e. unmanaged) data (byte*) to managed byte array with C++/CLI (array).

I tried Marshal::Copy (data is pointed to by const void* data and is

相关标签:
5条回答
  • 2020-12-28 17:17

    All these answers dance around the real misunderstanding in the original question.. The essential mistake made is that this code:

    System::Runtime::InteropServices::Marshal::Copy(new IntPtr(data), 
                                                    _Data, 
                                                    0, 
                                                    dataSize)
    

    is incorrect.. you don't new (or gcnew) an IntPtr. Its a value type. One of the answers shows this, but it doesn't point out the original misunderstanding. The correct code can be expressed this way:

    System::Runtime::InteropServices::Marshal::Copy(IntPtr((void *)data), 
                                                    _Data, 
                                                    0, 
                                                    dataSize)
    

    This confused me when I first started using these constructs also..

    IntPtr is a C# struct.. a value type.

    0 讨论(0)
  • 2020-12-28 17:23

    "IntPtr" is just a wrapper around a "void *". You shouldn't need the new syntax, just use of the explicit conversion operator.

    System::Runtime::InteropServices::Marshal::Copy( IntPtr( ( void * ) data ), _Data, 0, dataSize );
    

    Should work.

    0 讨论(0)
  • 2020-12-28 17:27

    The C++/CLI compiler is a bit obtuse about this. The formal definition of IntPtr is "native integer", it is not a pointer type. The C++ language however only allows conversion of void* to a pointer type. The CLI supports pointer types but there are very few framework methods that accept them. Marshal::Copy() doesn't. One of the three IntPtr constructors does.

    You have to whack the compiler over the head with a cast or by using the IntPtr constructor. It is anybody's guess if this will still work on a 128-bit operating system, I'm not going to worry about it for a while.

    0 讨论(0)
  • 2020-12-28 17:38

    As you've noted, Marshal::Copy (and .NET in general), is not const-safe.

    However, the usual C and C++ functions are. You can write either:

    array<byte>^ data_array =gcnew array<byte>(dataSize);
    pin_ptr<byte> data_array_start = &data_array[0];
    memcpy(data_array_start, data, dataSize);
    

    or to avoid pinning:

    array<byte>^ data_array =gcnew array<byte>(dataSize);
    for( int i = 0; i < data_array->Length; ++i )
        data_array[i] = data[i];
    
    0 讨论(0)
  • 2020-12-28 17:41

    System::Runtime::InteropServices::Marshal::Copy(new IntPtr((void*)data), _Data, 0, dataSize);

    Pay attention to (void*) which type-casts from (const void*) so new IntPtr constructor can take it as argument.

    0 讨论(0)
提交回复
热议问题