【问题标题】:Using methods from a COM class in Delphi在 Delphi 中使用 COM 类中的方法
【发布时间】:2017-01-17 09:00:06
【问题描述】:

我在 VB.NET 中创建了一个 COM 类。我正在尝试在 Delphi 5.0 中使用它。

我看过一些关于该主题的示例/问题,即:

Call C# dll from Delphi

http://www.drbob42.com/delphi/headconv.htm

http://edn.embarcadero.com/article/32754

还有其他,但这些都是处理基本功能而不是自定义对象。

首先,我使用regasm注册了我的VB.NET COM DLL。

我的 VB.NET COM 对象定义如下:

<ComClass(Bridge.ClassId, Bridge.InterfaceId, Bridge.EventsId)> _
Public Class Bridge

  ' A creatable COM class must have a Public Sub New() 
  ' with no parameters, otherwise, the class will not be 
  ' registered in the COM registry and cannot be created 
  ' via CreateObject.
  Public Sub New()
    MyBase.New()
  End Sub

  Public Function Quote(ByRef input As InObject) As ReturnObject
    BLABLA
  End Function

End Class

使用输入类:

<ComClass(InObject.ClassId, InObject.InterfaceId, InObject.EventsId)> _
Public Class InObject

End Class

还有一个 Result 类:

<ComClass(ReturnObject.ClassId, ReturnObject.InterfaceId, ReturnObject.EventsId)> _
Public Class ReturnObject

End Class

请不要注意类名和其中缺少代码。我只是想强调一下我是如何将它们定义为 COM 类的。

我找不到任何 Delphi 代码调用 COM 类中的方法或使用自定义对象作为输入和返回的示例。但是,从我上面展示的示例中,我认为 Delphi 中声明要使用的函数的行是这样的:

function Bridge.Quote(i: InObject): ReturnObject; external 'Bridge.dll';

编译失败。我收到一个错误:

函数需要结果类型

有什么明显的我做错了吗?

【问题讨论】:

  • 我在帖子中间说过,我更改了名称以简化事情,我想用 .NET 代码展示的只是 COM 类是如何注册的,因此可以忽略名称。谢谢。
  • 我无法将实际代码放在这里。更新班级名称以防人们错过我对他们的评论
  • 在 Delphi 函数声明中尝试使用 Variant 而不是 ReturnObject
  • 那也没用,同样的错误信息。
  • 您不能使用external 语句来导入COM 对象。您需要在 Pascal 代码中定义对象的 COM 接口,然后在运行时使用CoCreateInstance() 或等效函数实例化 COM 对象,然后使用接口访问它。您可以让 Delphi IDE 导入 .NET 程序集,这样它就可以提取相关的 COM 声明并为您生成合适的 Pascal 代码。

标签: vb.net delphi com


【解决方案1】:

要创建 ComObject,您有 2 个选项:

  • CoCreateInstance
    https://msdn.microsoft.com/de-de/library/windows/desktop/ms686615(v=vs.85).aspx
    这需要按照您之前的描述注册 ComObject。你可以这样称呼它:

    CoCreateInstance(YourClassID, nil, CLSCTX_INPROC_SERVER, YourInterfaceID, Result)

  • 您的 DLL 导出一个创建请求实例的函数。然后,您可以在加载 DLL 时导入此函数。无需注册。

    function MyFunc: IMyInterface; external 'MyDll.dll';

不要忘记使用两种语言都支持的合适的调用约定(如stdcall或cdecl)

【讨论】:

  • 感谢您的回复。我在delphi IDE中导入tlb文件然后使用Co Create,所以我有类似bridge := CoBridge.Create; input := CoInObject.Create; bridge.Quote(input);的东西
  • 抱歉忘记添加行尾,无法编辑评论。有了这个,虽然我在我的日志文件中收到一个通用错误,说“系统找不到指定的文件”,但我认为这是关于找不到 dll。我使用 regasm 注册了 dll,但不确定我是否在这里遗漏了什么。您认为我应该放弃这种方法并遵循您概述的内容吗?
  • Com-DLL 与您的可执行文件是同一平台吗?我假设你不能混合 WIn32/Win64
  • com DLL 是使用 VB 构建的,它在 windows 7 上编译,但编译为 32 位 (x86)。 Delphi 代码在 XP 上运行。
  • XP-Machine 上是否所有依赖项都可用?请先尝试让它在 W7 机器上运行。
【解决方案2】:

感谢 Alexander B 为我提供了正确的方向 - 我必须添加更多细节,否则我会选择他的输入作为正确答案。

因此,正如我在 cmets 中所述,我在 delphi GUI 中导入了 tld 文件并使用 CoClassName.Create 来访问对象。虽然这在运行时给了我错误,因为应用程序找不到 VB.NET dll,但即使我使用 regasm 导入了 dll,我也收到错误消息“系统找不到指定的文件”。然后我找到了以下帖子

Call C# dll from Delphi

这表明标志 /codebase 必须添加到 regasm 命令。一旦我使用带有此标志的 regasm 导入 dll,一切正常。希望这对其他人有帮助。

【讨论】:

    猜你喜欢
    • 2017-09-18
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 2011-08-03
    • 2023-03-05
    • 2010-10-02
    相关资源
    最近更新 更多