我必须使用头文件中具有以下签名的库中的方法:
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 *?
答案 0 :(得分:1)
&符号表示传递引用语义。换句话说,GetEvfFrame
函数会传递对size_t
值的引用,而不是size_t
值本身。
您的p / invoke签名应该使用ref
而不是out
。
答案 1 :(得分:1)
这与C ++ / C#interop无关。它实际上是关于C ++的。
C ++具有引用的概念。当您通过引用传递对象时,实际上是传递对象本身,而不仅仅是副本。这意味着对被调用者中对象的任何修改都将出现在调用者中。 C#与out
和ref
关键字具有相似的概念。
您可以这样测试:
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
修饰符基本相同。