0

我需要一个 C# 接口来通过 CLI 方言调用一些本机 C++ 代码。C# 接口在所需参数前面使用out属性说明符。这转化为 C++/CLI 中的%跟踪引用。

我的方法具有以下签名和主体(它正在调用另一个本机方法来完成这项工作):

virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed
{
    mRenderWindow->getMetrics(width, height, colourDepth, left, top);
}

现在由于一些编译时错误(都与 相关not being able to convert parameter 1 from 'unsigned int' to 'unsigned int &'),代码将无法编译。

作为一个谦虚的 C++ 程序员,在我看来,CLI 对于讲德语的人来说就像是荷兰语。可以做些什么来使这个包装器在 CLI 中正常工作?

4

3 回答 3

2

就像在已删除的答案中也建议的那样,我做了明显的并使用局部变量来传递相关值:

 virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed
        {
            unsigned int w = width, h = height, c = colourDepth;
            int l = left, t = top;
            mRenderWindow->getMetrics(w, h, c, l, t);
            width = w; height = h; colourDepth = c; left = l; top = t;
        }

由于跟踪引用的相当直观的机制,这有点明显:它们受到垃圾收集器工作的影响,并且&当它们很容易被放在内存中的其他位置时,它们并不是像普通引用那样真正的静态/常量。因此,这是解决问题的唯一可靠方法。感谢最初的回答。

于 2012-08-13T13:16:26.260 回答
0

如果您的参数在 C# 端使用“out”,您需要像这样定义您的 C++/CLI 参数:[Out] unsigned int ^%width

这是一个例子:

virtual void __clrcall GetMetrics([Out] unsigned int ^%width)
{
    width = gcnew UInt32(42);
}

然后在你的 C# 端,你会得到 42:

ValueType vt;
var res = cppClass.GetMetrics(out vt);
//vt == 42

为了在 C++/CLI 端使用 [Out] 参数,您需要包括:

using namespace System::Runtime::InteropServices;

希望这可以帮助!

于 2012-08-10T15:43:20.377 回答
0

您可以使用 pin_ptr 以便在本机代码更改它时不会移动“宽度”。托管端受到 pin_ptr 的影响,但如果您希望本机代码直接访问它而不使用“w”,我认为您无法解决这个问题。

virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed
        {
            pin_ptr<unsigned int> pw = &width; //do the same for height
            mRenderWindow->getMetrics(*pw, h, c, l, t);
        }
于 2014-10-30T18:06:30.877 回答