将 SWIG 与 C# 结合使用时的最佳实践是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 09:14:32  来源:igfitidea点击:

What are the best practices when using SWIG with C#?

提问by Dale Ragan

Has anybody out there used the SWIGlibrary with C#? If you have, what pitfalls did you find and what is the best way to use the library? I am thinking about using it as a wrapper for a program that was written in C and I want to wrap the header files where I can use them in my .NET application.

有没有人在C# 中使用SWIG库?如果有,您发现了哪些陷阱以及使用该库的最佳方式是什么?我正在考虑将它用作用 C 编写的程序的包装器,并且我想包装头文件,以便在我的 .NET 应用程序中使用它们。

编辑:对目标操作系统的一些说明。

I plan on running the application on Linux and Windows, therefore the reason I am looking into SWIG. P/Invoke is not an option.

我计划在 Linux 和 Windows 上运行该应用程序,因此我正在研究 SWIG。P/Invoke 不是一个选项。

采纳答案by Roark Fan

I think the mistake the earlier posters did was read the docs and not look at the examples.

我认为早期海报犯的错误是阅读文档而不是查看示例。

A few hours ago I needed to interface some C++ classes to C#. I looked in my Swig dir (I already had it for other work), found the directory Examples/csharp/class, browsed the code, loaded the solution, grokked it, copied it, put in my code, it worked, my job was done.

几个小时前,我需要将一些 C++ 类连接到 C#。我查看了我的 Swig 目录(我已经将它用于其他工作),找到了目录Examples/csharp/class,浏览了代码,加载了解决方案,对其进行了摸索,复制了它,放入了我的代码,它起作用了,我的工作完成了。

With that said, generated P/Invoke code isn't a solution for all needs. Depending on your project, it may be just as simple to write some simple API wrappers yourself or write managed C++ (Look up SlimDX for a superb example of this).

话虽如此,生成的 P/Invoke 代码并不是满足所有需求的解决方案。根据您的项目,自己编写一些简单的 API 包装器或编写托管 C++ 可能同样简单(查找 SlimDX 以获得这方面的极好示例)。

For my needs, it was simple and easy - I had mystuff.dll, and now in addition I can ship mystuffnet.dll. I'll agree that the doc is difficult to get into.

对于我的需要,它既简单又容易 - 我有mystuff.dll,现在另外我可以发货 mystuffnet.dll。我同意该文档很难进入。

Edit: I noticed the OP only mentioned C. For that, you don't really need Swig, just use the usual C#/C DLLImport interop syntax. Swig becomes useful when you want to let C++ classesbe invoked from C#.

编辑:我注意到 OP 只提到了 C。为此,您实际上并不需要 Swig,只需使用通常的 C#/C DLLImport 互操作语法即可。当您希望从 C# 调用C++ 类时,Swig 变得非常有用。

回答by Orion Edwards

I did attempt to use SWIG to wrap a project C++ for using in .NET a few years ago.

几年前,我确实尝试使用 SWIG 来包装在 .NET 中使用的项目 C++。

I didn't get very far as it was a massive giant pain to produce the configuration that SWIG required. At the time I just wanted a solution, not to learn another language/api/etc. SWIG may be easier to use these days, I couldn't tell you.

我没有走多远,因为生成 SWIG 所需的配置是一个巨大的痛苦。当时我只是想要一个解决方案,而不是学习另一种语言/api/等。这些天 SWIG 可能更容易使用,我不能告诉你。

We ended up using Managed C++ to wrap the C++ project. It worked really well.

我们最终使用 Managed C++ 来包装 C++ 项目。它工作得很好。

If you're just invoking functions straight out of a dll, I'd suggest not worrying about either of the above, and just using P/Invoke

如果您只是直接从 dll 中调用函数,我建议您不要担心上述任何一个,而只需使用P/Invoke

回答by Marc Bernier

For my last project, here's the entire C# SWIG configuration file:

对于我的最后一个项目,这里是整个 C# SWIG 配置文件:

%module mdProject

%{
#include "mdProject.h"
%}

I compiled it in SWIG with:

我在 SWIG 中编译了它:

swig -csharp -c++ -I../../Include mdProject.i

This generated a Project.cxx which I compiled and linked directly into the 'main' DLL, so I didn't need a second C++ 'helper' DLL. SWIG also generated a bunch of C# files which I compiled into a .NET DLL. My other wrappers (Java, PHP, etc) do use a helper DLL.

这生成了一个 Project.cxx,我将其编译并直接链接到“主”DLL,因此我不需要第二个 C++“助手”DLL。SWIG 还生成了一堆 C# 文件,我将它们编译成 .NET DLL。我的其他包装器(Java、PHP 等)确实使用了辅助 DLL。

As @patrick mentioned, SWIG uses P/Invoke, so if you have a problem with that, you'll need to find another solution.

正如@patrick 提到的,SWIG 使用 P/Invoke,因此如果您对此有疑问,则需要找到其他解决方案。

If you use types that stray from the ordinary (voids, structures, etc), you will have to do some extra work to get it right, but for the average API using int's, char*'s etc, it's fine.

如果您使用偏离普通的类型(void、结构等),您将不得不做一些额外的工作来使其正确,但对于使用 int、char* 等的普通 API,这很好。