C#非托管dll导出(工作原理)

12

我找到了一些库,可以将托管代码导出为非托管代码,以便您可以在像C/C++这样的非托管语言中使用它。但是我没有找到任何解释如何完成此操作的内容(这是我更感兴趣的内容)。

我正在寻找信息、教程、文章、代码源或任何可以帮助我理解这个过程的东西。

另外,如果你在你的书签中发现了一些钩子/拦截资源,我也很想阅读它们 :)

提前感谢并祝您拥有愉快的一天。


这是一个: https://www.nuget.org/packages/UnmanagedExports ,文档见 https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports - xanatos
2
那是我最初的话,我发现了那个库,阅读了所有的内容,但还是一无所获。我想要完全理解它,以至于可以自己编写代码。 - user3761832
1
你实际上从来没有说过你找到了哪个库! - MrPaulch
@user 黑魔法。我不是在开玩笑。如果里面有仙女,我也不会感到惊讶... - xanatos
1
没关系,因为我从来没有说过我需要一个只需插入即可使用的库。 - user3761832
1
但请注意,UnmanagedExports 可能是一个非常非常非常有经验的程序员的作品... 它涉及到 .NET 编程的 至少 四个“分支”:创建一个 nuget 包,将任务添加到 csproj,为 csproj 创建一个任务,使用 Mono.Cecil,IL Assembler。请记住,您可以安装它并使用 ILSpy 查看它... 它是根据 MIT 许可证授权的,所以可能没问题... 看起来没有它的源代码。 - xanatos
2个回答

9
我会发布一个答案,列出我写的评论。
目前最著名的用于完成这个任务的库是UnmanagedExports(至少截至今天)。它的页面位于https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports。遗憾的是没有源代码可用,但它基于MIT许可证,所以使用IlSpy来查看它也许没问题。
有一些关于如何完成此操作的参考文献。
Codeproject上至少有两篇文章:自动导出.NET函数到非托管程序的方法看起来是针对.NET 2.0,而非托管代码可以封装托管方法遗憾地只涉及到.NET 1.1。
在书籍Expert .NET 2.0 IL Assembler中大约在第384页有一些相关内容。
你当然可以做另一件事:观察UnmanagedExports的操作方式:UnmanagedExports最终由两部分组成:一个包含“愚蠢”的属性DllExportAttribute的程序集RGiesecke.DllExport.Metadata.dll,以及两个程序集(在我的电脑上nuget安装在packages\UnmanagedExports.1.2.6\tools文件夹中):RGiesecke.DllExport.dllRGiesecke.DllExport.MSBuild.dllUnmanagedExports的nuget安装程序会向csproj添加一些行,例如:
<Import Project="packages/UnmanagedExports.1.2.6/tools/RGiesecke.DllExport.targets" Condition="Exists('packages/UnmanagedExports.1.2.6/tools/RGiesecke.DllExport.targets')" />

导致执行包含在程序集RGiesecke.DllExport.MSBuild.dll中的类RGiesecke.DllExport.MSBuild.DllExportAppDomainIsolatedTask。该类使用Mono.Cecil重写程序集并进行一些代码重编织。此程序简单地调用ildasm生成il代码源,修改il代码源,然后使用ilasm生成“原始”的.dll/.exe。因此,简单来说,生成两个程序集,一个带有<Import />,另一个将<Import />注释掉,然后执行操作。
ildasm yourdll.dll /out=source.il

将两个文件进行比较,并使用您喜欢的文件比较器进行比较。

另一个有趣的链接在这里。有一些评论说明如何在x64上使其工作。

如果我要构建类似的东西,我可能会尝试将其集成到Fody中。这样我就可以免费获得整个后期生成任务(因为它由Fody完成)

无法使用Mono.Cecil实现... Mono.Cecil无法编写混合模式程序集(需要导出符号)。您必须使用UnmanagedExports(和其他各种示例)使用的相同“技巧”... 生成IL文件,修改它(它是一个文本文件,格式固定...非常容易修改),然后重新生成.dll/.exe文件。


1
IKVM.Reflection可以做到。http://weblog.ikvm.net/PermaLink.aspx?guid=aeaa0190-2b32-45e6-a249-3c3cf126372b - user423430
@user423430 是的 :-) - xanatos
3
现在有一个跟进/分支版本可用,是开源的:https://github.com/3F/DllExport/ - T.S

6
这里是维护在Github上的非托管导出源代码: https://github.com/3F/DllExport 非托管导出必须实现与C++/CLI编译器为反向PInvoke所做的基本相同的功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接