简体   繁体   English

C#unmanaged dll导出(如何工作)

[英]C# unmanaged dll exporting (how it works)

I have found libraries that would export managed code as unmanaged so you can use it by unmanaged languages like C/C++. 我发现,将托管代码导出为不受管理的 ,所以你可以像C / C ++语言的非托管使用库。 But I did not find anything that would explain how it's done (which is what I'm more interested in) 但我没有找到任何可以解释它是如何完成的(这是我更感兴趣的)

I'm looking for information, tutorials, articles, code sources or anything that could help me to understand how this works 我正在寻找信息,教程,文章,代码源或任何可以帮助我理解其工作原理的东西

On a side note, if you found some hooks/detours resources in your bookmarks I would love to read them too :) 另外,如果您在书签中找到了一些钩子/绕道资源,我也很乐意阅读它们:)

Thanks in advance and have a wonderful day. 在此先感谢您,祝您度过愉快的一天。

I'll post an answer, collecting the comments I wrote. 我会发一个答案,收集我写的评论。

The most famous library for doing it is (as today) the UnmanagedExports . 最着名的图书馆是(如今) UnmanagedExports Its page is https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports . 其页面为https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports Sadly there is no source code available, but it is licensed under the MIT license, so it is probably ok to use IlSpy to take a look at it. 遗憾的是,没有可用的源代码,但它是根据MIT许可证授权的,因此可以使用IlSpy来查看它。

There are a few references about how it is done. 关于它是如何完成的,有一些参考文献。

There are at least two articles on Codeproject: How to Automate Exporting .NET Function to Unmanaged Programs that seems to be for .NET 2.0 and Unmanaged code can wrap managed methods that sadly is about .NET 1.1. Codeproject上至少有两篇文章: 如何自动将.NET函数导出到非托管程序 ,似乎是针对.NET 2.0和非托管代码可以包装托管方法 ,遗憾的是.NET 1.1。

There is some reference in the book Expert .NET 2.0 IL Assembler around page 384. 第384页的Expert .NET 2.0 IL Assembler一书中有一些参考。

You can surely do another thing: observe what UnmanagedExports do: UnmanagedExports in the end is "composed" of two parts: an assembly RGiesecke.DllExport.Metadata.dll containing a "stupid" attribute DllExportAttribute plus two assemblies (that on my computer the nuget installs in the packages\\UnmanagedExports.1.2.6\\tools folder): RGiesecke.DllExport.dll and RGiesecke.DllExport.MSBuild.dll . 你肯定可以做另一件事:观察UnmanagedExports作用: UnmanagedExports最终由两部分“组成”:一个程序集RGiesecke.DllExport.Metadata.dll包含一个“愚蠢”属性DllExportAttribute加上两个程序集(在我的计算机上的nuget)安装在packages \\ UnmanagedExports.1.2.6 \\ tools文件夹中): RGiesecke.DllExport.dllRGiesecke.DllExport.MSBuild.dll The nuget installer of UnmanagedExports adds some lines to the csproj, like: UnmanagedExports的nuget安装程序为csproj添加了一些行,如:

<Import Project="packages/UnmanagedExports.1.2.6/tools/RGiesecke.DllExport.targets" Condition="Exists('packages/UnmanagedExports.1.2.6/tools/RGiesecke.DllExport.targets')" />

that cause the execution of the class RGiesecke.DllExport.MSBuild.DllExportAppDomainIsolatedTask contained in the assembly RGiesecke.DllExport.MSBuild.dll . 导致程序集RGiesecke.DllExport.MSBuild.dll包含的类RGiesecke.DllExport.MSBuild.DllExportAppDomainIsolatedTask的执行。 This class, using Mono.Cecil , rewrites the assembly doing some code reweaving. 这个类使用 Mono.Cecil重写了一些代码重新编写的程序集。 This program simply calls ildasm to generate the il code source, modifies the il code source and then uses ilasm to generate back the "original" .dll/.exe . 该程序只需调用ildasm来生成il代码源,修改il代码源,然后使用ilasm生成“原始”.dll / .exe。 So simply put, generate two assemblies, one with the <Import /> and another with the <Import /> commented out, then do a 所以简单地说,生成两个程序集,一个用<Import /> ,另一个用<Import />注释掉,然后做一个

ildasm yourdll.dll /out=source.il

of both files and compare it with your favourite file comparer. 两个文件并将其与您最喜欢的文件比较器进行比较。

Another interesting link is here . 另一个有趣的链接在这里 There are some comments to how to make it work on x64. 有一些评论如何使它在x64上工作。

If I had to build something similar, I would probably try to integrate it to Fody . 如果我必须构建类似的东西,我可能会尝试将它集成到 Fody In this way I would have the whole post-build Task for free (because it is done by Fody) 通过这种方式,我可以免费获得整个后期构建任务(因为它是由Fody完成的)

Can't be done with Mono.Cecil ... Mono.Cecil can't write mixed-mode assemblies (that are needed to export symbols). 无法使用Mono.Cecil ... Mono.Cecil无法编写混合模式程序集(导出符号所需)。 You have to use the same "trick" used by UnmanagedExports (and by the various other examples)... Generate the IL file, modify it (it is a text file in a fixed format... quite easy to modify), re-generate the .dll/.exe . 你必须使用UnmanagedExports(以及其他各种例子)使用的相同“技巧”...生成IL文件,修改它(它是一个固定格式的文本文件......很容易修改),重新 - 生成.dll / .exe。

Here is the source code of unmanaged exports maintained on github: 以下是github上维护的非托管导出的源代码:

https://github.com/3F/DllExport https://github.com/3F/DllExport

Unmanaged exports has to be doing essentially what c++/cli compiler has to do for reverse pinvoke. 非托管导出必须基本上是c ++ / cli编译器必须为反向pinvoke做的事情。

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

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