0

I have the need to call a C function via PInvoke from C#, passing a pointer to a struct, and this struct contains a pointer as well.

The struct can be simplified in C to,

struct myStruct {
  int myInt;
  float *myFloatPointer;
}

The function declaration can be simplified to

void myFunc(myStruct *a);

In C#, I declare the function as such

[DllImport("my_library.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void myFunc(ref myStruct a);

Unfortunately, I cannot determine how to declare the struct in C# with the pointer parameter present.

The C function does not allocate the memory pointed to by the float pointer, it only modifies it. I would prefer to solve this without the use of the unsafe keyword.

I have called functions via PInvoke with float* parameters successfully using float[], but that does not seem to work here.

Thanks in advance.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64

1 Answers1

2

C pointers are unsafe by nature, but you don't need to use the unsafe keyword here, even though the underlying concepts will be used.

You may declare the struct with an IntPtr:

struct myStruct
{
    public int myInt;
    public IntPtr myFloatPointer;
}

And initialize the field with Marshal method, after pinning the float array:

    float[] data = new float[15];
    myStruct ms = new myStruct();

    GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
    ms.myFloatPointer = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0);

This way, you don't make use of the unsafe keyword.

Be aware that depending on the Platform you are running on, the size of pointer and its alignment may vary; the structure might need some specific layout.

Florent DUGUET
  • 2,786
  • 16
  • 28