【问题标题】:Better way for pass by reference from C# to C++?通过引用从 C# 传递到 C++ 的更好方法?
【发布时间】:2009-08-03 16:26:02
【问题描述】:

我有一个 .h 文件的第 3 方集合以及随附的 .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);

我想一定有更好的方法,但也许不是?只是说我希望有更好的方法!

【问题讨论】:

    标签: c++-cli pass-by-reference


    【解决方案1】:

    一种选择是:

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

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

    【讨论】:

      【解决方案2】:

      您不使用固定指针而不是 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;
      };
      

      【讨论】:

      • 我想我真正想要避免的是显式分配回参数“testInt16”。我进行固定的唯一真正原因是试图将某些内容直接传递到本机调用中,这样我就可以避免这种显式分配。
      • 我会说固定的开销和复杂性比复制要多得多,当然对于任何原始大小的东西......
      猜你喜欢
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 2023-03-03
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      相关资源
      最近更新 更多