Reputation: 6467
I have a wrapper libary that uses c++/cli which calls unmanaged c++. I am calling this from c# and want to pass as a ref an int number.
public void MethodA()
{
int result = 0;
MethodCLI(ref result);
}
public void MethodCLI(int result)
{
//Singature of the method is
// UnmanagedC++(int* result);
UnmanagedC++(result);
}
How can I do this?
Thanks in advance
Upvotes: 1
Views: 394
Reputation: 941465
If the value update needs to be propagated back to the C# code (so the ref
keyword makes sense) then you have to declare the C++/CLI argument as int% result
. The exact syntactical equivalent of int&
in native C++.
However, it might be an "interior pointer" at runtime. You could for example pass a field of a class object in your C# code. Stored on the GC heap and that is an important detail. The GC might run while the native code is running (triggered by another thread for example) and move the object while it compacts the heap. That would make the pointer invalid. The C++/CLI compiler can't let that happen and will complain loudly if you try to pass result
directly to the native function. The basic reason why the C++/CLI designers chose different symbols for managed references (^
vs *
and %
vs &
).
Providing a stable pointer is required, the simplest way to do so is by passing a pointer to a value that is not stored on the GC heap. Like this:
public:
void MethodCLI(int% result)
{
int temp = result;
UnmanagedFunction(&temp);
result = temp;
}
The pin_ptr
keyword becomes useful if you need to pass an object instead of a value, it temporarily pins the passed object so the GC can't invalidate the pointer.
Upvotes: 2