2010-03-25 99 views
15

有没有办法从c头自动创建.net的p/invoke包装?从c头自动创建C#包装?

当然我可以手动创建它们,但维护它们会很痛苦,而且我可能会在某处导致错误,导致难以调试崩溃。

我试过SWIG,但它创建了完整的类,其中简单的结构就足够了。 SWIG的另一个问题是它需要c端的附加interop代码。

我宁愿如果输出在单声道也工作,但这不是必要的。

我可以使用的另一件事是解析c头文件,并创建一个像xml这样的好中间格式的输出,我可以从中自行创建C#包装。

编辑:
PInvoke Interop助理是我所需要的。
虽然有一些小问题:
*它将“无符号字符*”转换为字符串,我更喜欢IntPtr
*它假定size_t = int = long = 32位。这对我来说目前是正确的,但在每个平台上都可能不是这样。
有没有一个干净的方法来解决这个问题?否则,我会在转换它之前使用一些查找并替换c代码。

回答

10

PInvoke Interop Assistant应该更适合你,它专门设计用于处理C代码。

只要小心,没有工具可以给你100%保证的解决方案,C声明方式太模糊,以确保完全无故障的结果。指针造成的问题,在C代码中无处不在。没有办法知道指针用于读取或写入内存。或两者。或谁负责释放被指向的内存。

这是静态代码分析器的一个主要问题,如果他们不知道如何使用指针,他们就无法做出体面的工作。他们只能从使用中推断出来,但这是鸡与鸡蛋的问题,用法可能是错误的。微软在他们自己的头文件中使用了SAL annotations来解决这个问题,这个额外的标记对编译器来说是中性的,但可以被代码分析器解析。他们明确说明了预期用途的一个指针。

也被Pinvoke Interop Assistant使用,这就是为什么它可以在winapi声明上做得更好。但是,这当然只适用于微软头文件,这些SAL注释通常在繁忙的C程序员编写的代码上缺失。

+1

我同意Interop助理。请注意,虽然图形用户界面有一个恼人的bug(长度有限,如果你想翻译很多头文件很烦人),并且生成的位字段C#代码不仅非常难看,而且也是错误的(例如,你必须验证手动位字段代码)。除了位字段之外的任何东西,我发现它工作正常,但我对代码做的第一件事是删除冗长的名称空间(每个属性都有'System.Runtime.InteropServices')。 – OregonGhost 2010-03-25 17:13:53

+1

它有一些小问题。 它将“unsigned char *”转换为我更喜欢IntPtr的字符串,并假定int = long = 32位。有没有一个干净的方法来解决这个问题? 否则我会在转换它之前使用一些查找并替换c代码。 – Winner 2010-03-25 18:32:04

+1

这些是我警告过你的含糊之处。没有干净的方式,不得不修补生成的P/Invoke声明是正常的。 Btw:int和long在大多数C/C++代码中都是32位。 – 2010-03-25 18:38:26

1

如果我正确理解你的问题,你基本上是问是否有办法做SWIG的工作。

当然,你想要做的有点不同,所以一种选择是采取SWIG代码并改变它以你想要的方式工作。