Взаимодействие между C# и неуправляемой библиотекой C

У меня есть небольшая библиотека 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;
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
5 936
3

Ответы 3

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

Обновлять

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

Вы должны проверить инструмент, приведенный в этом журнале 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) ;

}

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

Суть была:

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

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

Другие вопросы по теме