简体   繁体   English

C#与非托管C库之间的互操作

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

I have a small C library in a DLL and I need to call a handful of its methods. 我在DLL中有一个小C库,我需要调用它的一些方法。

It uses pointers and a few structs but is otherwise quite simple. 它使用指针和一些结构,但在其他方面非常简单。 Problem is I'm not terribly knowledgable on .NET's interop with the unmanaged world and my attempts so far keep hitting memory access violation exceptions (presumably due to me not getting the pointers quite right). 问题是我对.NET与非托管世界的互操作并不是非常了解,到目前为止我的尝试仍然存在内存访问冲突异常(可能是因为我没有得到指针非常正确)。

Could anyone give me some pointers (ooh a pun!) on the best way to approach this? 有没有人能给我一些指针(哦,一个双关语!)以最好的方式来解决这个问题?

Thank you 谢谢

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;

You should check out the tool given in this MSDN Magazine article that can translate a C snippet to C# P/Invoke signatures, and of course the post as well. 您应该查看本MSDN杂志文章中提供的工具 ,该文章可以将C片段转换为C#P / Invoke签名,当然还有帖子。

Running the tool for your code snippet gives you this: 为您的代码段运行该工具可以为您提供:

[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) ;

}

Maybe you should write your wrapper in C++/CLI, because the interop between managed code and unmanaged code is very seamless. 也许你应该用C ++ / CLI编写你的包装器,因为托管代码和非托管代码之间的互操作是非常无缝的。

Update 更新

Here is a link to a trivial example: C data structure to mimic C#'s List>? 这是一个简单例子的链接: 模拟C#列表的C数据结构>?

I wrote a long and helpful answer, which StackOverflow discarded when I posted it. 我写了一篇很长且很有帮助的答案,StackOverflow在我发布它时丢弃了它。

The gist was: 要点是:

  1. You may find the site pinvoke.net useful, though it's not always accurate. 您可能会发现网站pinvoke.net很有用,但它并不总是准确的。
  2. The .NET framework source is a very useful repository of correct p/invoke signatures for Win32 functions, and has often given me inspiration for my own p/invoke problems. .NET框架源是一个非常有用的存储库,用于Win32函数的正确p / invoke签名,并且经常为我自己的p / invoke问题提供灵感。
  3. The Marshal class contains a lot of useful functions - some of which might help explain things like what you actually do with an IntPtr. Marshal类包含许多有用的函数 - 其中一些函数可能有助于解释像IntPtr实际执行的操作。

You may also need to be careful about fixed/pinning - particularly with something like your linked-list structure, thought I'm not sure how it will get used in your managed app. 您可能还需要注意固定/固定 - 特别是像您的链接列表结构,我认为我不确定它将如何在您的托管应用中使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM