Delphi / Win32的虚拟库接口? [英] Virtual Library Interfaces for Delphi/Win32?

查看:100
本文介绍了Delphi / Win32的虚拟库接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了这篇文章和找到虚拟库接口的概念,非常适合运行时加载DLL。但是似乎它们不适用于Win32。这是真的?如果是的话:为什么?我不明白什么会把想法与.NET结合起来。

I read this article and find the concept of Virtual Library Interfaces nice for runtime loading of DLLs. However it seems that they aren't available for Win32. Is this true? And if so: Why? I don't see what would tie the idea to .NET.

编辑:我已经在这里重写了Rob已经写过的内容了。 :-)

我不是在插件或类似的 - 这是关于简单的老Win32 DLL。对我来说,什么吸引人的想法是让编译器处理在运行时加载DLL的所有细节 - 不需要为DLL等中的每个函数调用GetProcAddress。

I'm mostly rephrasing here what Rob already wrote. :-)
I'm not after plugins or similar - it's about plain old Win32 DLLs. What appeals to me is the idea to let the compiler deal with all the details of loading a DLL at runtime - no need to call GetProcAddress for every function in the DLL etc.

推荐答案

在我看来,这三个答案到目前为止完全错过了你的问题。那个,还是我有你问为什么Win32 Delphi没有像哈维文章谈论的神奇的支持功能,不是吗?也就是说,给定DLL的名称和接口的类型信息的函数返回一个使用从DLL导出的独立函数来实现该接口的对象。

It seems to me like the three answers so far have completely missed the point of your question. That, or I have. You're asking why Win32 Delphi doesn't have something like the magical Supports function that Hallvard's article talks about, aren't you? Namely, a function that, given the name of a DLL and the type information of an interface, returns an object that implements that interface using the standalone functions exported from the DLL.

TJvPluginManager 要求插件DLL导出一个特殊的自我注册功能,管理员在加载DLL时将调用该函数,该函数必须返回 TJvPlugin 类,所以插件DLL必须用Delphi或C ++ Builder编写。另一方面,支持功能适用于使用任何语言编写的任何DLL。你可以在kernel32上使用它,如果你愿意的话。

Hydra seems to be all about calling .Net code from a Win32 program, not about importing functions from a DLL. TJvPluginManager requires that the plug-in DLLs export a special self-registration function that the manager will call when it loads the DLL, and the function must return an instance of the TJvPlugin class, so the plug-in DLL must be written in Delphi or C++ Builder. The Supports function, on the other hand, works with any DLL written in any language. You could use it on kernel32, if you wanted.

我不知道为什么Win32 Delphi没有这样的东西。可能CodeGear并没有看到很多的需求,因为Delphi和Turbo Pascal已经走了很久没有它。

I don't know why Win32 Delphi doesn't have such a thing. Maybe CodeGear didn't see much demand for it since Delphi and Turbo Pascal had already gone for so long without it.

当然有可能写一个类似于,而且我并不期望这个.Net版本一定要写得更难,除非微软的.Net库已经提供了大部分的功能,而且Delphi只是将它们包装成一个方便的调用函数像Delphi已有多年的支持的其他几个重载版本。

It's certainly possible to write a function that works like that, and I don't expect it would be any harder to write than the .Net version must have been, unless Microsoft's .Net libraries already provide most of the pieces and Delphi just wraps them up into a convenient-to-call function that looks like the several other overloaded versions of Supports that Delphi has had for years.

将有几个步骤在Win32中实现该功能。 (我只提供一个必要的草图,因为我现在没有Delphi的运行副本,很好地问,也许我会找到更多的细节。)首先,你需要确保类型一个接口的信息至少保留了其方法的未装饰名称。然后,支持将需要为接口中的每个方法生成一个函数存根(除了_AddRef,_Release和QueryInterface)。假设调用约定是 stdcall

There would be a few steps to implementing that function in Win32. (I'm providing only a sketch of what's necessary because I don't have a running copy of Delphi handy right now. Ask nicely, and maybe I'll find more details.) First, you'd need to make sure that type information for an interface held, at a minimum, the undecorated names of its methods. Then, Supports would need to generate a function stub for each method in the interface (besides _AddRef, _Release, and QueryInterface). The stub would go something like this, assuming the calling convention is stdcall:

asm
  // Pop the return address,
  // discard the "this" pointer,
  // and restore the return address
  pop eax
  pop ecx
  push eax

  jmp AddressOfFunction
end;

由于支持生成每个存根,填写实际的函数地址,从调用 GetProcAddress 获取相应的接口方法的名称。 stdcall 调用约定很容易包装; cdecl 有点麻烦; 注册是脖子上的痛苦。

As Supports generated each stub, it would fill in the actual function address, gotten from calling GetProcAddress with the name of the corresponding interface method. The stdcall calling convention is easy to wrap like that; cdecl is a little cumbersome; register is a pain in the neck.

一旦生成了所有存根,就需要生成一个看起来它实现了给定的接口的对象。它不一定是一个实际的课。在编译时,支持不知道将要求实现的接口的布局,所以有一个类不会太多。

Once it has all the stubs generated, it would need to generate an "object" that looks like it implements the given interface. It doesn't have to be an actual class. At compile time, Supports doesn't know the layout of the interface it's going to be asked to implement, so having a class wouldn't accomplish much.

最后一步是提供 _AddRef _Release 的实现, QueryInterface _AddRef 将不会显着; _Release 当引用计数达到零时,您可以调用 FreeLibrary QueryInterface 根本不会做太多的事情,除了声称它支持 IUnknown ,并且给出的$ 支持

The final step is to provide implementations of the _AddRef, _Release, and QueryInterface. _AddRef would be unremarkable; _Release is where you'd call FreeLibrary when the reference count reached zero; QueryInterface wouldn't do much at all, except claim that it supports IUnknown and the interface given to Supports.

Delphi曾经提供一个示例程序,演示了实现一个没有任何类的接口。所有这些都是使用记录和函数指针(完全是所有的接口)。 Delphi还带有相应的代码来做类,这部分是为了显示Delphi可以做多少事情。我现在找不到演示程序的名称,但我确定它仍然在某处。

Delphi used to come with a sample program that demonstrated implementing an interface without any classes at all. It was all done with records and function pointers (which is all an interface ultimately is, after all). Delphi also came with the corresponding code to do it with classes, in part to show how much easier Delphi can make things. I can't find the name of the demo program now, but I'm sure it's still around somewhere.

这篇关于Delphi / Win32的虚拟库接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆