2

首先,我是 Delphi 和 COM 的新手,但我应该在 Delphi 中构建 COM 应用程序。我在互联网上阅读了很多文章和笔记,但是我仍然不清楚Delphi中的COM和COM。

我的资料来源 - http://www.everfall.com/paste/id.php?wisdn8hyhzkt(大约 80 行)。

我尝试创建一个 COM 接口和 Impl 类 - 如果我从 Delphi 调用接口方法(我通过 TestClient.Create 创建一个 impl 对象),它可以工作,但是如果我尝试从外部世界创建一个对象(从 Java,通过 com4j ) 我的应用程序因以下异常而崩溃:

Project Kernel.exe raised exception class $C0000005 with 
message 'access violation at 0x00000002: read of address 0x00000002'.

如果我在 QueryInterface 中设置断点 - 它会中断,但是当我从函数中出来时 - 所有崩溃。

我做错了什么?我还缺少什么?我可以/应该读什么关于 COM(在 Delphi 中)以避免这样的愚蠢问题?

4

3 回答 3

2

无需自己实现 IUnkown.QueryInterface。从 TestComImpl 中删除该方法并让 TComObject 处理它。还要确保给 ITestCom 接口一个 GUID。

于 2010-04-23T12:46:41.307 回答
0

如果在 QueryInterface 返回后发生崩溃,我要做的是在 Java 应用程序调用 QueryInterface 时在 Java 应用程序中放置一个断点,然后查看它接下来尝试做什么。这会让你知道在哪里看。

你的评论似乎证实了这一点。它正在调用 QueryInterface,返回一个表明该接口良好的结果,并尝试将其用于立即中断的事情。但是,如果您注释掉告诉它接口良好的代码,它最终不会尝试使用该接口,并且没有任何问题。

如果您不熟悉 Delphi,访问冲突通常意味着空指针取消引用。在这里,它表示您的指令指针位于内存位置 0x000002。这可能意味着您以某种方式尝试在尚未构造的对象上调用虚拟方法(或接口方法)。

希望有帮助!

于 2010-04-23T12:07:29.493 回答
0

我从头开始用 COM 制作了一个 dll 并

  1. 我使用 DllRegisterServer - 它让我可以控制服务器注册(在我的第一次尝试中通过 TComObjectFactory.RegisterClassObject)
  2. 我从我的 TestComImpl 中删除 QueryInterface
  3. Com4j 仅支持 STA(Apartment)线程模型(我假设 RegisterClassObject 使用 MTA)
  4. 因此,如果类注册为 Apartment (STA) 或 Both - com4j 可以创建实例。

感谢大家的帮助!

于 2010-04-26T08:51:26.267 回答