我有一个用Pascal写的dll。我已经确定我需要在Java代码中运行CoInitialize,但我无法弄清楚如何。
我找到了另一个应该在这里提供帮助的Stack Overflow线程:https://stackoverflow.com/questions/15763993但我无法理解它是如何工作的。
我现在的代码是:
public interface CSQLLib extends StdCallLibrary {
CSQLLib INSTANCE = (CSQLLib) Native.loadLibrary("DatabaseLibrary", CSQLLib.class);
public HRESULT CoInitialize(Pointer p);
public HRESULT CoUninitialize();
public String doSQLQuery(String input);
public void DllMessage();
}
答案 0 :(得分:1)
使用 JNA 从 Java 代码调用 CoInitializeEx
的示例:
import com.sun.jna.platform.win32.Ole32;
public class Example {
public static void main(String[] args) {
Ole32.INSTANCE.CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED);
}
}
请注意,JNA docs 和 Windows SDK docs 都推荐使用 CoInitializeEx
而不是 CoInitialize
。 CoInitialize(null)
等价于 CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED)
,但 JNA 文档建议在 Java 应用程序中使用 COINIT_MULTITHREADED
(实际上,他们称其为“唯一明智的选择”)——然而,不管他们怎么说,某些 COM 接口只能与 COINIT_APARTMENTTHREADED
一起正常工作,因此它实际上取决于您使用的 COM 对象。无论您选择哪种方式,CoInitializeEx
都更好,因为它可以清楚地(而不是隐含地)您使用的是哪种 COM 线程模式。
请注意您在评论中提到的解决方案,从用 Delphi 编写的 DLL 中调用 CoInitialize
不是一个好习惯。 COM 应该在应用程序中而不是在 DLL 中初始化。如果您曾尝试在某个其他应用程序中重用您的 DLL(该应用程序已经在调用 CoInitialize
/CoInitializeEx
),您对它的调用很可能会因 S_FALSE
或 {{1} 而失败} 因为应用程序已经初始化了它。