P / Invoke Struct с указателями, C ++ из C # - PullRequest
1 голос
/ 29 июня 2009

Я пытаюсь вызвать C ++ dll со структурой и функцией, подобной

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

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

из 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);
    }

Мне показалось, что я чертовски близок, но когда я запускаю это, программа просто завершается с оператором return.

Есть идеи, где я ошибся?

Спасибо

Mark

Ответы [ 3 ]

1 голос
/ 30 июня 2009

Похоже, вы забыли указать соглашение о вызовах:

[DllImport("mydll.dll", EntryPoint="some_func", CallingConvention=CallingConvention.Cdecl)]
0 голосов
/ 29 июня 2009

Я бы порекомендовал несколько вещей помимо того, что предложил Ариэль.

  1. Переместите оператор some_func(ref someData) на свою строку перед return.
  2. Позвоните Marshal.FreeHGlobal после этой строки (в противном случае это будет утечка памяти).
  3. , если order эквивалентно длине массива, я бы пошел дальше и использовал это.
  4. Вам нужно указать упаковку? Может быть, ваша упаковка выключена?

Единственная другая идея, которую я могу предложить, - это использовать double* в вашей структуре и / или закрепить массивы с помощью оператора fixed.

0 голосов
/ 29 июня 2009

Вы отладили в some_func? Попробуйте windbg этой программы. Или используйте VS, но обязательно перехватывайте все исключения, а также включайте смешанную отладку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...