我试图使用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返回了错误的接口,或者ibar上的call函数调用了默认接口,而不是QueryInterface的结果。
我快速查看了jacob-1.17-x64.dll的JNI源代码,发现QueryInterface实现或call实现没有任何明显的问题,尽管我以前没有看过JNI代码,所以我可能遗漏了一些显而易见的东西。
雅各布附带了一个示例,即访问多个接口的samples/com/jacob/samples/atl,它与我一样使用QueryInterface。但是,我不能运行这个示例,因为它需要一个没有提供的MultiFace.dll。(源代码是提供的,但它是MSVC++特定的源代码,我不使用MSVC++)。
QueryInterface中的IID绝对是正确的,而且我的对象肯定没有中断;我可以使用商业Java桥接器的免费试用版以及Visual访问IBar。
雅各布被窃听了还是我做错了什么?
使用JRE 1.7.0_51-b13。
发布于 2014-05-02 02:32:39
事实上雅各布没事。问题是C++Builder XE5已经窃听了IDispatch的实现。如果您的QueryInterface为IDispatch加上您想要的接口的IID,那么您将得到一个有效的指针,但是它实际上指向您查询的原始接口,而不是新的接口。
其他访问方法都必须使用vtable绑定,因此它们不会遇到问题。
把这个答案留在这里,以防其他人有同样的问题和搜索。
到目前为止,我还没有找到解决办法。
https://stackoverflow.com/questions/22431739
复制相似问题