将 SWIG 与 C# 结合使用时的最佳实践是啥?
Posted
技术标签:
【中文标题】将 SWIG 与 C# 结合使用时的最佳实践是啥?【英文标题】:What are the best practices when using SWIG with C#?将 SWIG 与 C# 结合使用时的最佳实践是什么? 【发布时间】:2010-09-06 17:14:35 【问题描述】:有没有人在 C# 中使用过 SWIG 库?如果有,您发现了哪些陷阱以及使用该库的最佳方式是什么?我正在考虑将它用作用 C 编写的程序的包装器,并且我想包装头文件,以便在我的 .NET 应用程序中使用它们。
编辑:对目标操作系统的一些说明。我计划在 Linux 和 Windows 上运行该应用程序,因此我正在研究 SWIG。 P/Invoke 不是一个选项。
【问题讨论】:
【参考方案1】:对于我的上一个项目,这是整个 C# SWIG 配置文件:
%module mdProject
%
#include "mdProject.h"
%
我在 SWIG 中编译它:
swig -csharp -c++ -I../../Include mdProject.i
这生成了一个 Project.cxx,我将其编译并直接链接到“主”DLL,因此我不需要第二个 C++“助手”DLL。 SWIG 还生成了一堆我编译成 .NET DLL 的 C# 文件。我的其他包装器(Java、php 等)确实使用了辅助 DLL。
正如@patrick 所提到的,SWIG 使用 P/Invoke,因此如果您对此有疑问,则需要寻找其他解决方案。
如果您使用偏离普通类型的类型(空隙、结构等),则必须做一些额外的工作才能使其正确,但对于使用 int、char* 等的普通 API,这很好。
【讨论】:
我知道这是去年的事了。但你能分享一下你是如何“编译并直接链接到'主'DLL”生成的.cxx 文件的吗?我完全不知道你是如何做到这一点的。提前致谢! :) 您需要有“主”DLL 的源代码(在我的例子中是 C++)。我刚刚打开了 DLLs C++ 项目,将 SWIG 的自动生成的 C++ 文件添加到项目中并重新构建。如果您无权访问 DLL 的源代码,则无法执行此操作。换句话说,您不能将新的源文件增量地添加到现有的 DLL 中——整个东西必须通过添加新的源文件从头开始重新构建。很多时候,您无法访问源代码,因此您最终不得不在 C# 代码和 DLL 之间创建一个小小的“中间人”DLL。【参考方案2】:我认为早期的海报所犯的错误是阅读文档而不是查看示例。
几个小时前,我需要将一些 C++ 类与 C# 接口。我查看了我的 Swig 目录(我已经拥有它用于其他工作),找到目录 Examples/csharp/class
,浏览代码,加载解决方案,摸索它,复制它,放入我的代码,它工作,我的工作完成了。
话虽如此,生成的 P/Invoke 代码并不是满足所有需求的解决方案。根据您的项目,自己编写一些简单的 API 包装器或编写托管 C++ 可能同样简单(查找 SlimDX 以获得一个极好的示例)。
根据我的需要,这很简单——我有mystuff.dll
,现在我还可以发送mystuffnet.dll
。我同意该文档很难进入。
编辑:我注意到 OP 只提到了 C。为此,您实际上并不需要 Swig,只需使用 usual C#/C DLLImport interop syntax。当您希望从 C# 调用 C++ 类 时,Swig 会变得很有用。
【讨论】:
我认为 SWIG 即使对于 C 语言也很酷。您可以将过程式编程变成 oop!【参考方案3】:几年前,我曾尝试使用 SWIG 包装一个 C++ 项目,以便在 .NET 中使用。
我没有走得太远,因为生成 SWIG 所需的配置是一个巨大的痛苦。当时我只是想要一个解决方案,而不是学习另一种语言/api/等。这些天 SWIG 可能更容易使用,我不能告诉你。
我们最终使用托管 C++ 来包装 C++ 项目。效果非常好。
如果您只是直接从 dll 中调用函数,我建议您不要担心上述任何一种情况,而只需使用 P/Invoke
【讨论】:
以上是关于将 SWIG 与 C# 结合使用时的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章
将 Glassfish 与 IIOP 结合使用时的完整协议层次结构是啥