我正在尝试使用JACOB 1.17(最新的稳定版本)来访问64位进程内COM服务器,即MyObject-x64.dll。
我的CoClass有两个双接口:IFoo(默认)和IBar。 IFoo
包含foo_method()
,IBar
包含bar_method()
。两种方法的调度ID均为1。
我的Java代码是:
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.LibraryLoader;
import com.jacob.com.Variant;
// ...
ActiveXComponent my_object = new ActiveXComponent("MyObject.MyClass"); // OK
Dispatch.call(my_object, "foo_method"); // OK
Dispatch ibar = my_object.QueryInterface("{DE3FF217-120B-4F1E-BEF5-098B8ABDEC1F}"); // OK
Dispatch.call(ibar, "bar_method"); // Exception - "Can't map names to dispid:bar_method"
Dispatch.getIDOfName(ibar, "bar_method"); // Exception - "Can't map names to dispid:bar_method"
Dispatch.call(ibar, "foo_method"); // OK, executes foo_method
Dispatch.call(ibar, 1); // OK, executes foo_method
因此,似乎QueryInterface返回了错误的接口,或call
上的ibar
函数正在调用默认接口而不是QueryInterface的结果。
我已经快速浏览了jacob-1.17-x64.dll的JNI源代码,并且无法看到QueryInterface
实现或call
实现的任何明显问题,虽然我之前没有看过JNI代码所以我可能会遗漏一些明显的东西。
JACOB附带了一个示例,samples/com/jacob/samples/atl
访问多个接口,它使用与我相同的QueryInterface。但是我无法运行此示例,因为它需要未提供的MultiFace.dll。 (提供了源代码,但它是MSVC ++特定的源代码,我不使用MSVC ++)。
QueryInterface中的IID绝对是正确的,我的对象肯定没有被破坏;我可以通过免费试用其中一个商业Java-COM桥接器以及Visual Basic来访问IBar。
JACOB是否被窃听或者我做错了什么?
使用JRE 1.7.0_51-b13。
答案 0 :(得分:0)
实际上,雅各布还可以。问题是C ++ Builder XE5错误地实现了IDispatch。如果您使用IDispatch的QueryInterface加上您想要的接口的IID,那么您将获得一个有效的指针,但它实际上指向您查询的原始接口,而不是新接口。
其他访问方法都必须使用vtable绑定,因此它们没有遇到问题。
如果其他人有同样的问题和搜索,请留下此答案。
到目前为止,我还没有找到解决方法。