I have written a C++ wrapper function in CLR that calls a C# .dll to use in unmanaged C++. After calling the C# .dll, I want to copy (Marshal) the data into a struct to use in the unmanaged C++. Here is what I have so far and have verified it works:
The last thing I have to copy to the structure is a C# byte[]. I do not have a strong opinion on which type to copy (Marshal) the byte[] to. Does anyone have any suggestions on how I could get this to work? Or is there anything that I wasn't clear enough? Thanks in advance!
Answers
>> No, there is not a field that will indicate the number of elements in the array nor will it be fixed. I haven't ever worked with a SAFEARRAY but can give it a try and report back...strId, strStoreName, and strName are of the type std::basic_string<TCHAR>...
1. Just as I thought : strId, strStoreName, and strName are indeed STL strings (as defined in the <string> header file). However, since you used Marshal::StringToHGlobalUni() to convert the managed strings to unmanaged Unicode strings, I would personally declare them as std::wstring.
2. In this case, I think it would be better if the byte array member field of the unmanaged structure be declared as of type std::vector<unsigned char>. It would be more suitable since the other fields use the STL type string/wstring.
3. Here is how I have defined the unmanaged structure in my test managed C++ code :
4. The following is how I have defined the managed equivalent of the above structure in C# :
5. The following is a test API that I created in managed C++ to be called in an unmanaged C++ application :
The code above contained the code you have included in the OP. The last lines show how I have transformed the managed "byArray" into an unmanaged vector<unsigned char>.
- Bio.
Please visit my blog : http://limbioliong.wordpress.com/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Based on your description, it seems that you need to copy a C# byte[] to a C++ char[] , am I right?
Please take a look at this thread: http://stackoverflow.com/questions/289076/how-can-i-pass-a-pointer-to-an-array-using-p-invoke-in-c
It provides a way to pass a byte[] to a char* in a C API. It may give you some ideas.
Best regards,
Mike Feng
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
A few more points :
1. The std::vector also intrinsically contains information on the number of elements it holds, use : vector::size() to determine this.
2. In my example code, I first prepared the vector<unsigned char> to be able to contain the number of elements that are contained in the managed byte array :
3. Then I used the address of the first element of the vector as the target address for the later call to Marshal::Copy() :
Note that this (referencing vector[0]) is only possible provided the vector has been sized. The other way is to actually make the vector contain a value in vector[0] (e.g. by using push_back() to insert a value).
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
See if this code helps. I got this from an old project. Converts C# byte array to std::string:
转自: http://social.msdn.microsoft.com/Forums/no/clr/thread/82614307-f1d9-4f30-8418-541305d5f86c