Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameters from managed to unmanaged code

Tags:

c++

c#

I have to use a method from a library that has the following signature in the header file:

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

I am calling these from c# using the following:

[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);
}

I have displayInfo defined as a struct in c# as well.

My question is where there is any significance to the ampersand in the function signature in the header file? Why size_t& instead of size_t or char*& instead of char*?

like image 519
devprog Avatar asked Apr 22 '26 10:04

devprog


2 Answers

This has nothing to do with C++/C# interop. It's actually about C++.

C++ has the concept of references. When you pass an object by reference, you are actually passing the object itself, and not just a copy. That means any modification to the object in the callee will appear in the caller. C# has a similar concept with the out and ref keywords.

You can test it that way:

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

As to "why" there's an ampersand, well, it's probably because those are out parameters: that is, the caller wants the function to modify these values. This is done to circumvent the "single return value" restriction of C-like languages.

like image 106
Etienne de Martel Avatar answered Apr 24 '26 01:04

Etienne de Martel


The ampersand denotes pass-by-reference semantics. In other words, the GetEvfFrame function is passed a reference to a size_t value, not the size_t value itself.

Your p/invoke signature should really use ref rather than out.

like image 23
Kent Boogaart Avatar answered Apr 23 '26 23:04

Kent Boogaart