views:

166

answers:

2

I have a C# struct to represent a cartesian vector, something like this:

public struct Vector  
{  
    private double x;  
    private double y;  
    private double z;  

    //Some properties/methods
}

Now I have an unmanaged C dll that I need to call with P/Invoke. Some methods expect a double[3] parameter.

The unmanaged C signature is something like

void Cross(double a[3], double b[3], double c[3]);  

Is there any way to set up a P/Invoke signature so I can pass instances of my Vector struct and marshal them transparently to unmanaged double[3]? I would also need bidirectional marshaling as the unmanaged function needs to write the output to the argument array, so I guess I would need to marshal as LpArray.

A: 

I don't have my compilers to hand, but I wonder if you can use something like

[MarshalAs(...)]
[StructLayout(LayoutKind::Sequential, Pack=1)]
public struct Vector  
{  
    private double x;  
    private double y;  
    private double z;  

    //Some properties/methods
}

See here and here and here

Preet Sangha
+2  A: 

You can lie in your P/Invoke declaration, the members will align properly on all current CPU architectures to be readable as an array in unmanaged code:

[DllImport("blah.dll")]
private static extern void Cross(ref Vector a, ref Vector b, ref Vector c);
Hans Passant
Ouch... so simple! It worked just fine. Many thanks
Pedro