- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我读到this article并发现虚拟库接口(interface)的概念非常适合 DLL 的运行时加载。但它们似乎不适用于 Win32。这是真的?如果是这样:为什么?我不明白这个想法与 .NET 有什么联系。
编辑:我在这里主要是改写 Rob 已经写过的内容。 :-)
我不追求插件或类似的东西 - 它是关于普通的旧 Win32 DLL。吸引我的是让编译器在运行时处理加载 DLL 的所有细节的想法 - 无需为 DLL 中的每个函数调用 GetProcAddress 等。
最佳答案
在我看来,到目前为止的三个答案完全没有捕获你的问题的要点。那个,或者我有。您在问为什么 Win32 Delphi 没有 Hallvard 的文章中提到的神奇的 Supports
功能,不是吗?也就是说,一个函数,在给定 DLL 的名称和接口(interface)的类型信息的情况下,返回一个使用从 DLL 导出的独立函数实现该接口(interface)的对象。
Hydra 似乎只是从 Win32 程序调用 .Net 代码,而不是从 DLL 导入函数。 TJvPluginManager
要求插件 DLL 导出一个特殊的自注册函数,管理器在加载 DLL 时将调用该函数,并且该函数必须返回 TJvPlugin
的实例类,因此插件DLL必须用Delphi或C++ Builder编写。另一方面,Supports
函数适用于用任何语言编写的任何 DLL。如果您愿意,您可以在 kernel32 上使用它。
我不知道为什么Win32 Delphi没有这样的东西。也许 CodeGear 没有看到对它的太多需求,因为 Delphi 和 Turbo Pascal 已经很长时间没有它了。
当然可以编写一个像这样工作的函数,而且我不认为它会比 .Net 版本更难编写,除非 Microsoft 的 .Net 库已经提供了大部分功能并且 Delphi只是将它们包装到一个方便调用的函数中,该函数看起来像 Delphi 多年来使用的 Supports
的其他几个重载版本。
在 Win32 中实现该函数需要几个步骤。 (我只提供必要内容的草图,因为我现在手头没有 Delphi 的运行副本。好好询问,也许我会找到更多详细信息。)首先,您需要确保该类型接口(interface)的信息至少包含其方法的未修饰名称。然后,Supports 需要为接口(interface)中的每个方法(除了 _AddRef、_Release 和 QueryInterface 之外)生成一个函数 stub 。假设调用约定为 stdcall
, stub 将如下所示:
asm
// Pop the return address,
// discard the "this" pointer,
// and restore the return address
pop eax
pop ecx
push eax
jmp AddressOfFunction
end;
当 Supports
生成每个 stub 时,它将填充实际的函数地址,该地址是通过使用相应接口(interface)方法的名称调用 GetProcAddress
获得的。 stdcall
调用约定很容易像这样包装; cdecl
有点麻烦; 注册
是一件令人头疼的事。
一旦生成了所有 stub ,它就需要生成一个看起来像实现给定接口(interface)的“对象”。它不一定是一个实际的类(class)。在编译时,Supports
不知道它将被要求实现的接口(interface)的布局,因此拥有一个类不会完成太多任务。
最后一步是提供 _AddRef
、_Release
和 QueryInterface
的实现。 _AddRef
不会太引人注目; _Release
是当引用计数达到零时调用 FreeLibrary
的地方; QueryInterface
根本不会做太多事情,除了声称它支持 IUnknown
以及为 Supports
提供的接口(interface)。
Delphi 曾经附带一个示例程序,该程序演示了无需任何类即可实现接口(interface)。这一切都是通过记录和函数指针完成的(毕竟,这最终只是一个接口(interface))。 Delphi 还附带了相应的代码来使用类来完成此操作,部分原因是为了展示 Delphi 可以使事情变得多么容易。我现在找不到演示程序的名称,但我确信它仍然在某个地方。
关于delphi - Delphi/Win32 的虚拟库接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/662875/
有WHERE 1=1有什么作用如果您在脚本(伪代码)中编写此请求: sql = "SELECT f1,f2,f3 FROM t WHERE 1=1" ++ restOfTheClause
这个问题已经有答案了: R: Convert delimited string into variables (3 个回答) 已关闭 5 年前。 我有一个包含电影数据的表,在最后一列中,它包含电影所属
假设我有一个基类: struct A{ virtual void foo() = 0; }; 然后假设我有一个这样的派生类: struct B : public virtual A{ voi
我有一个小问题,我的 << 运算符没有被正确调用。 这是我的: class SomeInterface { friend std::ostream& operator<<(std::ostrea
首先,我来自 Java 社区,并且仍然是 C++ 的学习者。 请看下面的类 第二张图片显示了类“GameObject”的子类。它还有一个 Display() 方法。 GameObject类有5个子类,
我这里遇到了一些问题。我试图让我的代码像 java 中的接口(interface)一样工作。这个类被其他 2 个继承,因为它们导致了一些问题。而且我还想知道我是否做对了,以及改进我的代码的方法。我是新
在 C++ 中,我有一个基类 A,一个子类 B。两者都有虚方法 Visit。我想在 B 中重新定义“访问”,但 B 需要访问每个 A(以及所有子类)的“访问”功能。 我有类似的东西,但它告诉我 B 无
我有一个抽象类,它是类层次结构的根。该根类有一个带有一些简单实现的方法,似乎没有必要随时随地更改该实现。 使该方法成为非虚方法很好,但是某些子类可能会意外地重新实现它。在这种情况下,虚拟 final方
在 MSDN 上,我发现在抽象方法声明中使用“virtual”修饰符是错误的。我的一位同事应该是非常有经验的开发人员,但他在他的代码中使用了这个: public abstract class Busi
C++ 虚函数表是仅用于确定调用虚函数时应该执行哪一段代码,还是在运行时有其他用途? 在维基百科上,它列出了“动态调度”作为一个原因,但没有深入了解 C++ 的更多细节...... 最佳答案 一些实现
页面大小是否恒定?更具体地说,getconf PAGE_SIZE 给出 4096,这很公平。但这可以通过程序的运行时间改变吗?或者它在整个操作系统进程生成过程中是否保持不变。 IE。 , 进程是否可能
析构函数(当然还有构造函数)和其他成员函数之间的区别在于,如果常规成员函数在派生类中具有主体,则仅执行派生类中的版本。而在析构函数的情况下,派生版本和基类版本都会被执行? 很高兴知道在析构函数(可能是
如果一个函数被定义为虚函数并且与纯虚函数相同,这究竟意味着什么? 最佳答案 来自 Wikipedia's Virtual function... In object-oriented programm
我有一个在 Jetty 下运行的应用程序,我希望该应用程序返回自引用绝对 URL(生成 RSS 提要时,因此客户端必须能够在没有“当前 URL”上下文的情况下工作)。 问题是我事先不知道应用程序将部署
如何在两个virtualtreeview之间复制以复制所有列,而不仅仅是第一列? 复制前: 复制后: 最佳答案 树控件不保存任何数据。它不包含要显示的列数据,因此无法复制它。而是,当树控件想要显示任何
我已将 ShowHint 设置为 true 并将 HintMode 设置为 hmToolTip,但是当我将光标悬停在控件上时,我的 OnGetHint() 事件处理程序甚至没有断点。 知道我做错了什么
我的 friend 正在 Delphi 中使用 VirtualTreeView 工作,并且遇到了下一个问题:他有两列,第一列的每一行都有数据和子项。是否可以不更改第一列宽度来设置最大子列宽度? 图例:
我在我的 Virtual TreeView Component 中使用 TVirtualStringTree ( Delphi project 的一部分)我想创建一个 View ,其中 2 列可以有可
我想遍历 VirtualTreeView 的所有根并将其删除。 我不想清除它。 我收到此代码的访问冲突: var Node : PVirtualNode; begin if VirtualStri
我有一个可以输出表单的 PHP 文件。我想在服务器端调用这个 PHP 文件(当前使用“include”),填写并提交。 这样更好,因此我不必干预实际的 PHP 表单,只需处理表示层,以便数据可以被它自
我是一名优秀的程序员,十分优秀!