Reputation: 823
After posting a question yesterday I thought I had this cleared up but I'm still having problems, I have a C++/CLI wrapper for a C++ class, some functions of the C++ class take buffers for recv as parameters, the packet structures are defined as C++ structs and that is what is taken as a parameter.
In C# I have replicated these C++ structs using structlayout so that I have equivalent structs in C# which are laid out the same in memory as my C++ structs. In my C++/CLI code I attempted the following
UINT GetValues(value class^ JPVals) // value class, as C# structs are value types
{
IntPtr ptr;
Marshal::StructureToPtr(JPVals,ptr,false);
return m_pComms->GetValues(ptr,0); // m_pComms is a wrapped unmanaged class
//GetValues takes a pointer to a C++ struct
}
The error I get is cannot convert parameter 1 from 'System::IntPtr' to 'SJPVal *', why is it not possible to Marshall from value class to C++ struct pointer? And in this case what should I be passing in and how should I be marshalling it?
Upvotes: 1
Views: 4408
Reputation: 8431
You didn't get the serialization process:
// !! Note the % !!
UINT GetValues(value class% JPVals) // value class, as C# structs are value types
{
// Allocate a buffer for serialization, pointer to NULL otherwise
IntPtr ptr = Marshal::AllocHGlobal(Marshal::SizeOf(JPVals));
try {
// Serialize the managed object to "static" memory (not managed by the GC)
Marshal::StructureToPtr(JPVals, ptr, false);
// Pass it to unmanaged code that will modify it.
auto ret = m_pComms->GetValues(reinterpret_cast<SJPVal*>(ptr.ToPointer()), 0);
// Copies the modifications back
Marshal::PtrToStructure(ptr, JPVals);
// Free resources
Marshal::FreeHGlobal(ptr);
return ret;
} catch (...) {
// Make sure we free the memory
Marshal.FreeHGlobal(ptr);
throw;
}
}
EDIT: shown how to copy back the value.
As you are using a C# struct
you need to pass it by reference to make sure the changes are copied back. Alternatively, the code will work the same with a C# class
. The first step (StructureToPtr
) is probably useless, now, since you probably don't care about what was in there before your call to GetValues
.
By the way your naming convention is a bit bad. You should NOT start variable names by a capital letter in C++.
Upvotes: 1