从 C# 到 C++ 通过引用传递的更好方法?

发布于 2024-07-30 10:56:45 字数 562 浏览 1 评论 0原文

我有一个 .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);

我认为必须有更好的方法,但也许不是? 只是说我希望有更好的方法!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里寻她 2024-08-06 10:56:45

一个选择是这样做:

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

因此,您只需创建一个本地本机变量并避免巨大的强制转换和 .NET 指针内容。

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.

梦亿 2024-08-06 10:56:45

您不使用固定指针而不是 GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer() 的原因是什么?

像这样固定参考值也为时已晚。

如果引用是对堆栈值的引用,则不需要,如果它是对实例字段的引用,则调用代码应该真正固定该对象(尽管这是将非托管语义混乱地泄漏到托管代码中,但它至少使以下行为 由于 ref参数

非常小,因此完全避免所有固定并在堆栈上创建一个临时参数,将其传递给非托管函数,然后将其写回原始函数是有意义的。

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

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;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文