簡體   English   中英

C#與非托管C庫之間的互操作

[英]Interop'ing between C# and an unmanaged C library

我在DLL中有一個小C庫,我需要調用它的一些方法。

它使用指針和一些結構,但在其他方面非常簡單。 問題是我對.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;

您應該查看本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) ;

}

也許你應該用C ++ / CLI編寫你的包裝器,因為托管代碼和非托管代碼之間的互操作是非常無縫的。

更新

這是一個簡單例子的鏈接: 模擬C#列表的C數據結構>?

我寫了一篇很長且很有幫助的答案,StackOverflow在我發布它時丟棄了它。

要點是:

  1. 您可能會發現網站pinvoke.net很有用,但它並不總是准確的。
  2. .NET框架源是一個非常有用的存儲庫,用於Win32函數的正確p / invoke簽名,並且經常為我自己的p / invoke問題提供靈感。
  3. Marshal類包含許多有用的函數 - 其中一些函數可能有助於解釋像IntPtr實際執行的操作。

您可能還需要注意固定/固定 - 特別是像您的鏈接列表結構,我認為我不確定它將如何在您的托管應用中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM