Question

I have a 3rd party collection of .h files along with the .lib files that go with them. I am wrapping those native C++ files with a C++/CLI wrapper and making final calls from C#. I have an issue when I call methods that expect a reference to be passed in where the value is not getting changed in my wrapper unless I explicitly change it.

My C++/CLI wrapper code currently looks like this:

bool get_testInt16(int16% testInt16)
{
   int16* t = static_cast<int16*>(GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer());
   bool b = m_NativeCMTY_TestData->get_testInt16(*t);
   testInt16 = *t;
   return b;
};

And the corresponding native C++ code looks like:

bool get_testInt16(int16 &testInt16);

I figure there's gotta be a better way, but maybe not? Let just say I'm HOPING there's a better way!

Was it helpful?

Solution

An option would be to do:

bool get_testInt16(int16% testInt16)
{
   int16 t = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(t);
   testInt16 = t;
   return b;
};

So you simply create a local native variable and avoid the huge cast and .NET pointer stuff.

OTHER TIPS

any reason you're not using pinning pointers instead of GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer()?

Also pinning the referenced value like this is too late.

If the reference is to a stack value it is unneeded, if it is a reference to an instance field then the calling code should really pin the object (though this is a messy leakage of unmanaged semntics into managed code it at least makes the behaviour of the method clear.

Since the ref parameter is so small it would make sense to just avoid all the pinning entirely and create a temporary one on the stack, pass that through to the unmanaged function and then write it back to the original.

bool get_testInt16(int16% testInt16)
{
   int16 temp = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(temp);
   testInt16 = temp;
   return b;
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top