The following topics briefly compare Microsoft® Win32® and OLE functions and code.
Using the ole attribute of the @dll.import directive, you can do the following:
In theory, the functions exported from Ole32.dll and Oleaut32.dll are no different from any other DLL function. In practice, the OLE functions follow a consistent calling style of their own. OLE functions differ from Win32 functions in the following ways:
In the Win32 style of coding, a simple Add function looks like this:
int sum; sum = Add(10, 20);
In OLE style, the Add function looks like this:
HRESULT hr; int sum; hr = Add(10, 20, &sum); if (FAILED(hr)) { ...handle error.. }
The OLE mode takes advantage of this consistent coding style to provide an easy way to call OLE functions from Java. Invoking an OLE-style Add function from Java looks much like invoking a more traditional Win32-style function.
/** dll.import("OLELIKEMATHDLL", ole) */ private native static int Add(int x, int y); int sum = Add(10, 20); // If we got here, Add succeeded.
Declaring a parameter as type String on an OLE mode function passes a LPCOLESTR. The Microsoft VM also includes a preceding length prefix so the String can also be treated as a BSTR.
Declaring a return value as type String in OLE mode causes the Microsoft VM to pass a pointer to an uninitialized LPCOLESTR*. When the native function returns, the Microsoft VM will convert the returned LPCOLESTR to a Java String, and then call CoTaskMemFree to free the String.
The system class com.ms.com._Guid is used to represent GUIDs. Passing a _Guid object as a parameter passes a pointer to a GUID to the native function. Declaring a return type of _Guid causes the Microsoft VM to pass a pointer to an uninitialized GUID that the function fills in (in OLE mode only).
For example, OLE32 exports the functions CLSIDFromProgID and ProgIDFromCLSID to map between CLSIDs and the human-readable names used by the Microsoft® Visual Basic® function CreateObject. These functions have the following prototypes.
HRESULT CLSIDFromProgID(LPCOLESTR szProgID, LPCLSID pclsid); HRESULT ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lpszProgId);
In Java, you would declare these methods in the following way.
import com.ms.com._Guid; class OLE { /** @dll.import("OLE32", ole) */ public static native _Guid CLSIDFromProgID(String szProgID); /** @dll.import("OLE32", ole) */ public static native String ProgIDFromCLSID(_Guid clsid); }
Caution Do not confuse com.ms.com._Guid with the obsolete com.ms.com.Guid (with no underscore).
Declaring a parameter to be type com.ms.com.Variant passes a pointer to a VARIANT to the native function. Declaring a return value to be type com.ms.com.Variant (OLE mode only) passes a pointer to an uninitialized Variant for the native function to fill in.
To pass a COM interface pointer, you must generate a Java/COM interface class using a tool such as Jactivex.exe. You can then pass or receive COM interfaces by declaring a parameter to be of that interface type.
For example, the system class com.ms.com.IStream is a Java/COM interface that represents the Structured Storage IStream* interface. The OLE32 function CreateStreamOnHGlobal could be declared as follows.
import com.ms.com.*; /** @dll.import("OLE32", ole) */ public static native IStream CreateStreamOnHGlobal(int hGlobal, boolean fDeleteOnRelease);
For more information about COM interface pointers, see Integrating Java and COM.