What's the appropiate signature/marshall attribute to be able to get output params using pointers params? So far I tried this:
// Function to calculate the norm of vector. !0 on error.
// int err_NormVec(int size, double * vector, double * norm)
[DllImport("vectors.dll")]
int err_NormVec(int size, double[] vector, ref double norm)
The previous approach doesn't pop back the value to .NET from C. I also tried to use pinned GCHandle, with the IntPtr signature.
[DllImport("vectors.dll")]
int err_NormVec(int size, double[] vector, IntPtr norm)
public void doSomething()
{
double norm = 0;
// ...
GCHandle handle = GCHandle.Alloc(norm, GCHandleType.Pinned);
int status = err_NormVec(vector.Lenght, vector, handle.AddrOfPinnedObject());
// ... clean gchandle, check status and so on
}
In this case I got the value back but on the GCHandle.Target, not on the original norm. Which is annoying. I would like to be able to pin the intptr of the norm it self not just a copy.
What is the appropiate signature to return a value using a pointer? Is there a supported way to get a IntPtr to an int value?
This works for me (as it should):
//C++ DLL (__stdcall calling convention)
extern "C" __declspec(dllexport) void Foo(double *result) {
*result = 1.2;
}
//C#
class Program
{
[DllImport( "Snadbox.dll", CallingConvention=CallingConvention.StdCall )]
static extern void Foo( ref double output );
static void Main( string[] args )
{
double d = 0;
Foo( ref d );
Console.WriteLine( d ); // prints "1.2"
}
}
Passing the double
using the ref
keyword is sufficient. So, I am led to believe that there is something wrong (or misunderstood) in the implementation. Can you post the implementation for us?
Also, perhaps you are building the C++ version using the default calling convention (cdecl
), but .NET is using StdCall
. Have you made sure that these line up? You may crash if they are mixed, but there is no guarantee. For instance, in my example, if I change the C++ side to cdecl
then the out parameter is read back as 0.