在 Visual Studio 2010 Express 中从 dll 自动生成 C# 包装器类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11668932/
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-09 18:43:56  来源:igfitidea点击:

Automatically generate C# wrapper class from dll in Visual Studio 2010 Express?

c#dllwrappervisual-studio-express

提问by mre

I was told by a colleague of mine that Visual Studio allows one to point to a .dlland auto-magically generate a C# wrapper class. Is this really possible? And if so, how does one go about achieving this? I've browsed the web, but have failed to come up with anything!

我的一位同事告诉我,Visual Studio 允许指向 a.dll并自动神奇地生成 C# 包装器类。这真的可能吗?如果是这样,人们将如何实现这一目标?我浏览了网页,但没有想出任何东西!

Thanks all!

谢谢大家!



Figured I'd share these resources as well,

想我也会分享这些资源,

采纳答案by Darin Dimitrov

3 cases:

3种情况:

  1. The DLL represents a managed assembly => you directly reference it in your project and use it
  2. The DLL represents a COM object => you could use the tlbimp.exeutility to generate a managed wrapper
  3. The DLL represents an unmanaged library with some exported functions. That's the toughest one. There are no tools. You will have to consult the documentation of the library to know the exported function names and parameters and build managed P/Invoke wrappers. You could use the dumpbin.exeutility to see a list of exported functions. Here's an articleon MSDN about the different steps.
  1. DLL 代表一个托管程序集 => 你直接在你的项目中引用它并使用它
  2. DLL 表示 COM 对象 => 您可以使用tlbimp.exe实用程序生成托管包装器
  3. DLL 表示带有一些导出函数的非托管库。那是最难的。没有工具。您必须查阅库的文档以了解导出的函数名称和参数并构建托管 P/Invoke 包装器。您可以使用dumpbin.exe实用程序查看导出函数的列表。这是MSDN 上有关不同步骤的文章

回答by Hans Passant

This certainly isn't possible with any DLL. Just a very specific kind, one that implements a COM server. The converter needs a good description of the exported types, that's provided for such servers by a type library.

这对于任何 DLL 肯定是不可能的。只是一种非常特殊的类型,实现了 COM 服务器。转换器需要对导出的类型进行很好的描述,类型库为此类服务器提供了这些描述。

A type library is the exact equivalent to metadata in a managed assembly. While it starts life as a standalone file, a .tlb file, it often gets embedded as a resource in the DLL. Good place for it, keeps the type descriptions close to the code that implements it. Just like the metadata in a .NET assembly.

类型库完全等同于托管程序集中的元数据。虽然它开始时是一个独立的文件,一个 .tlb 文件,但它通常作为资源嵌入到 DLL 中。它的好地方,使类型描述靠近实现它的代码。就像 .NET 程序集中的元数据一样。

Some tooling to play with to see type libraries (not sure if it works in Express): in Visual Studio use File + Open + File and pick, say, c:\windows\system32\shell32.dll. You'll see the resources in that DLL, note the TYPELIB node. That's the type library. It is binary so actually reading it isn't practical. For that, run OleView.exe from the Visual Studio Command Prompt. File + View Typelib and select the same DLL. That decompiles the type library back into IDL, the Interface Description Language that was originally used to create the type library. Highly readable, you'll have little trouble understanding the language. And can easily see how the .NET Tlbimp.exe can translate that type library into equivalent C# declarations.

可以使用一些工具来查看类型库(不确定它是否适用于 Express):在 Visual Studio 中使用 File + Open + File 并选择 c:\windows\system32\shell32.dll。您将看到该 DLL 中的资源,注意 TYPELIB 节点。那就是类型库。它是二进制的,所以实际上阅读它是不切实际的。为此,请从 Visual Studio 命令提示符运行 OleView.exe。File + View Typelib 并选择相同的 DLL。这会将类型库反编译回 IDL,IDL 是最初用于创建类型库的接口描述语言。可读性强,理解语言不会有什么问题。并且可以很容易地看到 .NET Tlbimp.exe 如何将该类型库转换为等效的 C# 声明。

Type libraries are old, they have been around since 1996. Originally designed by the Visual Basic team at Microsoft, as a replacement for VBX, the 16-bit VB extensibility model. They have been verysuccessful, practically any Windows compiler supports them. But they are limited in expressive power, there is no support for things like generics and implementation inheritance. Notable is that the Windows 8 team has replaced type libraries for WinRT. They picked the .NET metadata format.

类型库很旧,它们从 1996 年就出现了。最初由 Microsoft 的 Visual Basic 团队设计,作为 VBX(16 位 VB 可扩展性模型)的替代品。它们非常成功,几乎任何 Windows 编译器都支持它们。但是它们的表达能力有限,不支持泛型和实现继承之类的东西。值得注意的是,Windows 8 团队已经替换了 WinRT 的类型库。他们选择了 .NET 元数据格式。

回答by Benjamin Basmaci

I know this question is fairly old and seems to have been answered sufficiently, but I just want to add one thought I think might be important. I could be totally wrong, so please take my answer with a grain of salt and correct me on this if I am.

我知道这个问题已经很老了,似乎已经得到了充分的回答,但我只想补充一个我认为可能很重要的想法。我可能完全错了,所以请保留我的答案,如果我是的话,请纠正我。

To be able to call members/fields in a DLL, the information needed to call them must be accessible in some form. That information should be all you need to write a wrapper. With that, you can determine all members/fields "form" aka method headers and so on.

为了能够调用 DLL 中的成员/字段,调用它们所需的信息必须可以某种形式访问。这些信息应该是编写包装器所需的全部信息。有了它,您可以确定所有成员/字段“形成”又名方法标题等。

In C# it is possible to load DLLs via reflection and get that information. I dont know about different DLL-Types as described above, but as I said, to call the members/fields this information has to be there in some form. So using reflection to get that Information, you could generate a new class e.g. "prefixOriginalname" and have it have the same members/fields as your original class, calling the members/fields of your original class and adding your desired extra functionality.

在 C# 中,可以通过反射加载 DLL 并获取该信息。我不知道上述不同的 DLL 类型,但正如我所说,要调用成员/字段,这些信息必须以某种形式存在。因此,使用反射来获取该信息,您可以生成一个新类,例如“prefixOriginalname”,并使其具有与原始类相同的成员/字段,调用原始类的成员/字段并添加所需的额外功能。

So

所以

  1. Every DLL (or peripheral document) gives you the information need to use its types. Namely everything that is implemented as "public"
  2. You can access this needed information via reflection
  3. Given 1. and 2., you can create a program to extract the needed information from DLL and generate wrappers accordingly.
  1. 每个 DLL(或外围文档)都为您提供使用其类型所需的信息。即所有实现为“公共”的东西
  2. 您可以通过反射访问这些所需的信息
  3. 鉴于 1. 和 2.,您可以创建一个程序来从 DLL 中提取所需的信息并相应地生成包装器。

As I said, I am not 100% sure on this one, because the other answers make it sound to me like that might be too difficult or even impossible for some reason.

正如我所说,我对这个不是 100% 确定,因为其他答案让我觉得这可能由于某种原因太难甚至不可能。