cs0815
cs0815

Reputation: 17388

PInvoke - Method's type signature is not PInvoke compatible

This is the header file signature and C code I am trying to use in C#:

__declspec(dllexport) emxArray_real_T *emxCreateWrapper_real_T(real_T *data, int32_T rows, int32_T cols);

struct emxArray_real_T
{
    real_T *data;
    int32_T *size;
    int32_T allocatedSize;
    int32_T numDimensions;
    boolean_T canFreeData;
};

emxArray_real_T *emxCreateWrapper_real_T(real_T *data, int32_T rows, int32_T
  cols)
{
  emxArray_real_T *emx;
  int32_T size[2];
  int32_T numEl;
  int32_T i;
  size[0] = rows;
  size[1] = cols;
  emxInit_real_T(&emx, 2);
  numEl = 1;
  for (i = 0; i < 2; i++) {
    numEl *= size[i];
    emx->size[i] = size[i];
  }

  emx->data = data;
  emx->numDimensions = 2;
  emx->allocatedSize = numEl;
  emx->canFreeData = FALSE;
  return emx;
}

I am currently trying to invoke it as follows in C#:

[DllImport(@"C:\bla\bla.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern emxArray_real_T emxCreateWrapper_real_T(double[,] data, int rows, int cols);

double[,] array2D = new double[,] { { 1 }, { 3 }, { 5 }, { 7 } };
var x = emxCreateWrapper_real_T(array2D, 1, 4);

but get:

Method's type signature is not PInvoke compatible.

emxArray_real_T currently looks like this:

[StructLayout(LayoutKind.Sequential)]
public struct emxArray_real_T
{
    //public IntPtr data;
    //public IntPtr size;
    double[] data;
    int[] size;
    public int allocatedSize;
    public int numDimensions;
    [MarshalAs(UnmanagedType.U1)]
    public bool canFreeData;
}

Upvotes: 0

Views: 1421

Answers (1)

Simon Mourier
Simon Mourier

Reputation: 138915

There are multiple problems. First of all your C++ function returns a pointer (emxArray_real_T *) but your import declaration returns a struct. That cannot work. Also, you declare data as double[,] in the import declaration, but as double[] in the structure. Suggestions:

  • Replace the struct by a class
  • Determine if data should be a double[] or a double[,]
  • Also check the final size of real_T. I believe it's a platform dependent variable that could be float (32 bit) or double (64 bit).

Upvotes: 1

Related Questions