我有.h文件的第三方集合以及随附的.lib文件。我使用C ++ / CLI包装器包装这些本机C ++文件,并从C#进行最终调用。我有一个问题,当我调用期望传递引用的方法时,我的包装器中的值没有被更改,除非我明确地更改它。
我的C ++ / CLI包装器代码目前如下所示:
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;
};
相应的本机C ++代码如下所示:
bool get_testInt16(int16 &testInt16);
我认为必须有更好的方法,但也许不是吗?我只想说我正在希望有更好的方法!
答案 0 :(得分:4)
可以选择:
bool get_testInt16(int16% testInt16)
{
int16 t = testInt16;
bool b = m_NativeCMTY_TestData->get_testInt16(t);
testInt16 = t;
return b;
};
因此,您只需创建一个本地本机变量,并避免使用巨大的强制转换和.NET指针。
答案 1 :(得分:0)
你没有使用固定指针代替GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer()
的任何原因吗?
同样如此固定参考值也为时已晚。
如果引用是堆栈值则不需要,如果它是对实例字段的引用,那么调用代码应该真正固定对象(尽管这是一个混乱的非托管semntics泄漏到托管代码中它至少会使方法的行为明确。
由于ref参数太小,所以完全避免所有的pinning并在堆栈上创建一个临时的,将其传递给非托管函数然后将其写回原始函数是有意义的。
bool get_testInt16(int16% testInt16)
{
int16 temp = testInt16;
bool b = m_NativeCMTY_TestData->get_testInt16(temp);
testInt16 = temp;
return b;
};