I’ve got a dll written in Pascal. I’ve determined that I need to run CoInitialize in the Java code, but I just can’t figure out how.
I found another Stack Overflow thread which should have helped here: https://stackoverflow.com/questions/15763993 but I couldn’t understand how it actually worked.
My current code that I have now is here:
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(); }
Advertisement
Answer
Example of calling CoInitializeEx
from Java code using JNA:
import com.sun.jna.platform.win32.Ole32; public class Example { public static void main(String[] args) { Ole32.INSTANCE.CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED); } }
Note that use of CoInitializeEx
is recommended by both the JNA docs and the Windows SDK docs instead of CoInitialize
. CoInitialize(null)
is equivalent to CoInitializeEx(null,Ole32.COINIT_APARTMENTTHREADED)
, but the JNA docs recommend using COINIT_MULTITHREADED
instead in Java apps (indeed, they call it “the only sane choice”) – however, despite what they say, some COM interfaces only work correctly with COINIT_APARTMENTTHREADED
, so it really depends on the COM objects you are using. Whichever you choose, CoInitializeEx
is better because it makes it obvious (rather than implicit) which COM threading mode you are using.
Note the solution you mentioned in your comment, calling CoInitialize
from within your DLL written in Delphi, is not a good practice. COM should be initialised in the application not in a DLL. If you ever attempt to reuse your DLL in some other application (which is already calling CoInitialize
/CoInitializeEx
), it is likely your call to it will fail with S_FALSE
or RPC_E_CHANGED_MODE
because the application will have already initialised it.