[英]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: 要点是:
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.