tags:

views:

604

answers:

3

I'm attempt to call a C++ dll with a struct and function like

struct some_data{
  int size,degree,df,order;
  double *x,*y,lambda;
};

extern "C"{    
   __declspec(dllexport) double *some_func(some_data*);
}

from C#:

  [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct SOME_DATA
    {
        public int size;
        public int degree;
        public int df;
        public int order;
        public System.IntPtr x;
        public System.IntPtr y;
        public double lambda;
    }

    [System.Runtime.InteropServices.DllImportAttribute("mydll.dll",EntryPoint="some_func")]
    public static extern System.IntPtr some_func(ref SOME_DATA someData);

    public IntPtr some_funcCall(){
        double[] x = new double[] { 4, 4, 7, 7 };
        double[] y = new double[] { 2, 10, 4, 22 };

        SOME_DATA someData = new SOME_DATA();

        someData.x = Marshal.AllocHGlobal(x.Length * Marshal.SizeOf(typeof(double)));
        Marshal.Copy(x, 0, someData.x, x.Length);
        someData.y = Marshal.AllocHGlobal(y.Length * Marshal.SizeOf(typeof(double)));
        Marshal.Copy(y, 0, someData.y, y.Length);       
        someData.size = 50;
        someData.degree = 3;
        someData.df = 50;
        someData.order = 4;
        someData.lambda = 1;            

        return some_func(ref someData);
    }

I thought I was pretty dang close, but when I run this, the program just quits at the return statement.

Any ideas where I've gone wrong?

Thanks,

Mark

A: 

Have you debugged into some_func? Try to windbg that program. Or use VS, but make sure to catch all exceptions and also enable mixed debugging.

Ariel
Yup, finally got back to this to debug. It was an error in the C++.
Mark
A: 

I would recommend a few things beyond what Ariel has suggested.

  1. Move the some_func(ref someData) statement to its own line before the return.
  2. Call Marshal.FreeHGlobal after that line (otherwise, it will be a memory leak).
  3. if order is equivalent to the array length, I would go ahead and use that.
  4. Do you have to specify the packing? Maybe your packing is off?

The only other idea I can suggest is to use double* in your struct and/or pin the arrays using the fixed statement.

Erich Mirabal
A: 

Seems like you forget to specify calling convention:

[DllImport("mydll.dll", EntryPoint="some_func", CallingConvention=CallingConvention.Cdecl)]
arbiter