Unmanaged Exports 修正版 .NET导出非托管函数
Unmanaged Exports 是一个将.NET编写的静态托管函数导出成可供C/C++等直接调用的非托管函数的工具。
它是如何工作的?
创建一个新的或者修改已经存在的类库。
然后加入 UnmanagedExports Nuget 包。
这基本就是所有要做的事情了。
然后你就可以随便写一些静态方法,用[DllExport]装饰它,然后在原生代码中使用了。
它很像 DllImport,你可以用MarshalAsAttribute来定义该函数的参数和结果的格式。
在编译时,这个工具会自动修改IL代码增加导出声明。
限制
- 你不能导出在同一个class中的重载函数,即便你指定了不同的导出名称。
- 另一个限制是你不能递归调用导出函数。
这看起来是运行时的限制,并且我并不想为了规避这些限制而再把你的函数做一次包装。
首先用C#(其它.NET语言也可)创建一个windows经典桌面dll,然后在Nuget中搜索并安装Unmanaged Exports这个包。
随后编写你要导出的静态函数,并添加[DllExport]注解,范例如下:
class Test { [DllExport("add", CallingConvention = CallingConvention.Cdecl)] public static int TestExport(int left, int right) { return left + right; } }
然后生成平台选择一个具体的平台(不能是AnyCPU否则该工具不生效),生成解决方案即可。
该工具最新版只支持vs2008以后的vs,因为vs2008及以前的版本不支持nuget。
工具官方网站及详细说明:
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
关于编译错误
该工具在非英文操作系统上可能会出现编译错误的问题,具体表现如下:
http://stackoverflow.com/questions/20288469/cant-create-unmanaged-dll-using-c-sharp-and-robert-gieseckes-unmanaged-exports
主要原因是因为非英文操作系统中IL代码中含有非英文注释导致插件工作异常。
虽然将系统语言切换成英文可以解决这个问题,但是这个方法过于麻烦,故本人修改了这个工具,修正了其在非英文操作系统上不能正常使用的问题。
文末附上修改后的文件,解压后将其中的两个dll替换进项目NuGet包中packages\UnmanagedExports.1.2.7\tools文件夹下的两个同名dll即可。
改修正版仅针对Unmanaged Exports 1.2.7版本制作,其它版本未测,可能不能正常使用。
替换完成后即可正常编译:
修正了非英文系统编译错误的Unmanaged Exports 1.2.7
抱图留名
建议给作者写邮件说明此问题并附上解决方案。让他更新一下nuget仓库,可以方便更多的人。
我使用的环境是中文版win10+中文版vs ultimate(没有完整安装,只安装了c#和c++开发功能)。在此环境下,此修复版仍然无法工作,仍然需要切换至英文版系统。
版本正确么?
UnmanagedExport 还是很有用的。
我也写了一篇文章. The Ultimate Guide to Calling .NET Methods and Classes from Native C/C++ Using Unmanaged Exports, 如果喜欢的话,可以把它翻译成中文,发表在这里。
现在有了更新的DllExport(https://github.com/3F/DllExport),看起来更厉害的样子,而且和Unmanaged Exports的作者也有一定的关系,应该可以放心使用。
Nice啊!