将参数从托管代码传递到非托管代码

时间:2011-06-10 14:31:27

标签: c# c++

我必须使用头文件中具有以下签名的库中的方法:

NKREMOTELIB_API int __stdcall GetEvfFrame(
    const unsigned char*& buffer,
    size_t& size,
    NKRemoteEvfDisplayInfo& displayInfo);

我使用以下内容从c#调用这些:

[DllImport("NKRemoteLib.dll")]
public static extern int GetEvfFrame(out IntPtr buffer, out IntPtr size, out NKRemoteEvfDisplayInfo displayInfo);

private void Test() {
    IntPtr size = new IntPtr();
    IntPtr buffer = new IntPtr();
    NKRemoteEvfDisplayInfo displayInfo;
    int res = GetEvfFrame(out buffer, out size, out displayInfo);
}

我将displayInfo定义为c#中的结构。

我的问题是头文件中函数签名中的&符有什么意义?为什么size_t&而不是size_t或char *&而不是char *?

3 个答案:

答案 0 :(得分:1)

&符号表示传递引用语义。换句话说,GetEvfFrame函数会传递对size_t值的引用,而不是size_t值本身。

您的p / invoke签名应该使用ref而不是out

答案 1 :(得分:1)

这与C ++ / C#interop无关。它实际上是关于C ++的。

C ++具有引用的概念。当您通过引用传递对象时,实际上是传递对象本身,而不仅仅是副本。这意味着对被调用者中对象的任何修改都将出现在调用者中。 C#与outref关键字具有相似的概念。

您可以这样测试:

void f(int i)
{
    i = 5; 
}
void g(int &i)
{
    i = 5;
}

int i = 0, j = 0;
f(i);
g(j);
std::cout << i; // should print 0
std::cout << j; // should print 5

至于“为什么”有一个&符号,好吧,这可能是因为那些是out参数:也就是说,调用者希望函数修改这些值。这样做是为了规避C语言的“单一返回值”限制。

答案 2 :(得分:0)

&符号(&)代表“参考”。这与您的c#out修饰符基本相同。