有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JNA在加载dll时调用CoInitialize

我有一个用Pascal编写的dll。我已经确定需要在Java代码中运行CoInitialize,但我就是不知道如何运行

我发现了另一个堆栈溢出线程,它应该在这里有所帮助: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();
}

共 (1) 个答案

  1. # 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 docsWindows SDK docs都建议使用CoInitializeEx,而不是CoInitializeCoInitialize(null)相当于CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED),但JNA文档建议在Java应用程序中使用COINIT_MULTITHREADED(事实上,他们称之为“唯一明智的选择”)——然而,尽管他们这么说,一些COM接口只能与COINIT_APARTMENTTHREADED一起正确工作,因此这实际上取决于您使用的COM对象。无论您选择哪一种,CoInitializeEx都会更好,因为它使您使用的COM线程模式变得明显(而不是隐含)

    请注意,您在评论中提到的解决方案,即从用Delphi编写的DLL中调用CoInitialize,并不是一种好的做法。COM应该在应用程序中初始化,而不是在DLL中初始化。如果您试图在其他应用程序(已经在调用CoInitialize/CoInitializeEx)中重用DLL,那么您对它的调用很可能会失败,因为应用程序已经对其进行了初始化