Взаимодействие между C # и неуправляемой библиотекой C - PullRequest
3 голосов
/ 11 декабря 2008

У меня есть небольшая библиотека C в DLL, и мне нужно вызвать несколько ее методов.

Он использует указатели и несколько структур, но в остальном довольно прост. Проблема в том, что я не очень хорошо осведомлен о взаимодействии .NET с неуправляемым миром, и мои попытки до сих пор продолжают поражать исключения нарушения доступа к памяти (вероятно, из-за того, что я не совсем правильно понимаю указатели).

Может ли кто-нибудь дать мне несколько советов (о, каламбур!) О том, как лучше всего подойти к этому?

Спасибо

extern vconfig_t *Pobsopen(Ppoly_t ** obstacles, int n_obstacles);


extern int Pobspath(vconfig_t * config, Ppoint_t p0, int poly0,
            Ppoint_t p1, int poly1,
            Ppolyline_t * output_route);

extern void Pobsclose(vconfig_t * config);

struct vconfig_t {
    int Npoly;
    int N;
    Ppoint_t *P;
    int *start;
    int *next;
    int *prev;
};

typedef struct Ppoly_t {
    Ppoint_t *ps;
    int pn;
} Ppoly_t;

typedef Ppoly_t Ppolyline_t;

typedef struct Pxy_t {
    double x, y;
} Pxy_t;

typedef struct Pxy_t Ppoint_t;
typedef struct Pxy_t Pvector_t;

Ответы [ 3 ]

5 голосов
/ 11 декабря 2008

Вам следует воспользоваться инструментом , приведенным в этом журнале MSDN статья , который может преобразовать фрагмент кода C в сигнатуры C # P / Invoke, и, конечно, пост.

Запуск инструмента для вашего фрагмента кода дает вам следующее:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct vconfig_t {

    /// int
    public int Npoly;

    /// int
    public int N;

    /// Ppoint_t*
    public System.IntPtr P;

    /// int*
    public System.IntPtr start;

    /// int*
    public System.IntPtr next;

    /// int*
    public System.IntPtr prev;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct Ppoly_t {

    /// Ppoint_t*
    public System.IntPtr ps;

    /// int
    public int pn;
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct Pxy_t {

    /// double
    public double x;

    /// double
    public double y;
}

public partial class NativeMethods {

    /// Return Type: vconfig_t*
    ///obstacles: Ppoly_t**
    ///n_obstacles: int
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Pobsopen")]
public static extern  System.IntPtr Pobsopen(ref System.IntPtr obstacles, int n_obstacles) ;


    /// Return Type: int
    ///config: vconfig_t*
    ///p0: Ppoint_t->Pxy_t
    ///poly0: int
    ///p1: Ppoint_t->Pxy_t
    ///poly1: int
    ///output_route: Ppolyline_t*
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Pobspath")]
public static extern  int Pobspath(ref vconfig_t config, Pxy_t p0, int poly0, Pxy_t p1, int poly1, ref Ppoly_t output_route) ;


    /// Return Type: void
    ///config: vconfig_t*
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Pobsclose")]
public static extern  void Pobsclose(ref vconfig_t config) ;

}
1 голос
/ 11 декабря 2008

Я написал длинный и полезный ответ, от которого StackOverflow отказался, когда я его опубликовал.

Суть была:

  1. Сайт pinvoke.net может оказаться полезным, хотя он не всегда точен.
  2. Исходный код .NET Framework является очень полезным хранилищем правильных сигнатур p / invoke для функций Win32 и часто вдохновляет меня на мои собственные проблемы p / invoke.
  3. Класс Marshal содержит множество полезных функций, некоторые из которых могут помочь объяснить такие вещи, как то, что вы на самом деле делаете с IntPtr.

Возможно, вам также нужно быть осторожным с фиксированным / закреплением - особенно с чем-то вроде структуры связанного списка, хотя я не уверен, как она будет использоваться в вашем управляемом приложении.

1 голос
/ 11 декабря 2008

Возможно, вам следует написать свою обертку на C ++ / CLI, потому что взаимодействие между управляемым кодом и неуправляемым кодом очень бесшовное.

Обновление

Вот ссылка на тривиальный пример: Структура данных C для имитации списка C #>?

...