简体   繁体   English

自动执行C ++库的C#包装

[英]Automatically perform C# wrapping of a C++ library

I've done a bit of research around this before posting but I couldn't find a direct answer specific to my environment. 在发布之前我已经对此进行了一些研究,但我找不到特定于我的环境的直接答案。

I have a third party library written in C++. 我有一个用C ++编写的第三方库。 I have access to the .dll , .lib and .h headers of the library. 我可以访问库的.dll.lib.h标题。

I'd like to wrap the library for use in C# using p/invoke. 我想使用p / invoke包装库以在C#中使用。 I'd like to know what options I have in terms of doing this and maintaining it. 我想知道我在做这个维护它方面有什么选择。 My hope here is that with the .h headers I can utilize some application to automatically provide the wrapper code. 我希望在这里,使用.h头文件,我可以利用一些应用程序自动提供包装器代码。

I'm interested in all kinds of solutions including commercial software solutions and any pitfalls of trying to automatically manage the wrapper code. 我对各种解决方案感兴趣,包括商业软件解决方案以及尝试自动管理包装器代码的任何缺陷。

You could try SWIG which is free. 你可以尝试免费的SWIG You may be able to script it to run automatically as part of a build process. 您可以将其编写脚本以在构建过程中自动运行。

Personally I'd just write some wrappers using [DllImport] . 就个人而言,我只是使用[DllImport]编写一些包装器。 Do you really need to access everything in the C++ library from C#? 你真的需要从C#访问C ++库中的所有内容吗? Often I've found you really only need to call a few functions, and the simplicity of dllimport is great 通常我发现你真的只需要调用一些函数,而dllimport的简单性很棒

My hope here is that with the .h headers I can utilize some application to automatically provide the wrapper code. 我希望在这里,使用.h头文件,我可以利用一些应用程序自动提供包装器代码。

It would be lovely if this were possible, but it is not. 如果这是可能的话会很可爱,但事实并非如此。 It is not possible because the header file does not contain enough information to determine how to marshal parameters. 这是不可能的,因为头文件不包含足够的信息来确定如何编组参数。 For instance, consider this declaration: 例如,请考虑以下声明:

void foo(int *x);

What is x ? 什么是x Its type is int* , pointer to int . 它的类型是int* ,指向int指针。 But is it a pointer to a single int value, or is it an array of int ? 但它是一个指向单个int值的指针,还是一个int数组? You simply cannot tell from the header file. 你根本无法从头文件中分辨出来。 You need to read the documentation. 您需要阅读文档。

And what about data flow. 那么数据流呢? Is the information flowing into the native code, or out of it, or in both directions? 信息是流入本机代码还是流出本机代码,还是两个方向? Again, that detail cannot be expressed a header file. 同样,该细节不能表示为头文件。

Now, there are various annotation conventions that can help with this. 现在,有各种注释约定可以帮助解决这个问题。 Essentially these are macros that evaluate to nothing that can be read by a tool and so help with conversion. 基本上这些宏是评估为工具无法读取的任何内容,因此有助于转换。 You see Win32 API functions annotated with _In_ , _In_Opt_ , etc. These can help, but only the very simplest of libraries can be automatically translated into p/invoke declarations. 您会看到使用_In__In_Opt_等注释的Win32 API函数。这些可以提供帮助,但只有最简单的库才能自动转换为p / invoke声明。

Now, if you are prepared to add extra annotation to the raw header files then you might have a chance. 现在,如果您准备为原始头文件添加额外注释,那么您可能有机会。 It is certainly possible that existing tools exist that will do a good job so long as you express the missing information in comments or macros. 只要您在注释或宏中表达缺少的信息,现有的工具肯定有可能做得很好。 SWIG is certainly worth a look, and there are other tools. SWIG当然值得一看,还有其他工具。

The fundamental point of my answer is to try to get across the idea that such translations are not as automatic as you might hope. 我的答案的基本点是试图理解这样的翻译并不像你希望的那样自动。 Personally, I always end up writing my p/invoke declarations by hand. 就个人而言,我总是手工编写我的p / invoke声明。 This allows me to get them exactly the way I want, and maintenance is not really a big deal because DLL interfaces typically don't change. 这允许我完全按照我想要的方式获取它们,并且维护并不是什么大问题,因为DLL接口通常不会改变。 They don't change because you don't want to break binary compatibility. 它们不会更改,因为您不想破坏二进制兼容性。

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

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