Hi,
I am using the JNIWrapper as 30 days evaluation. While my practicing i am trying to load a custom dll given to me by some thirdparty.
There are number of issues that are creating problem to me. First, there are some classes made in that dll, and the function i want to call are the member of these classes.
Suppose the class name is myClass and it has 3 function (loadData, populateDevice, getDeviceHandle). The class is in turn loaded by a global function which takes the class variable as pointer.
hr = CoCreateInstance(CLSID_MyClassDatabase, NULL, CLSCTX_ALL , IID_ClassDatabase, (PVOID *)&pMyClass);
That was the code from the sample C++ file given to me. Now i am unable to understand that how can i make MyClass type object in JAVA (in C++ it is pMyClass, the last arguement of the function) and then populate it using the CoCreateInstance with the signatures given above. Please Help me out a.s.a.p.
Hi,
Apparently for your purposes you also need our ComfyJ product
http://www.teamdev.com/comfyj/index.jsf , but not only JNIWrapper.
Using ComfyJ (more precisely the CodegenForComfyJ utility that is available in ComfyJ distribution archive) you can easily generate Java wrappers for COM objects/interfaces/types that are defined in the required COM type library.
Then you can create a necessary COM object in your Java application. The code snippet below demonstrates how it works:
// Initialize COM in the current Java thread
ComFunctions.coInitialize();
// Create COM object
IUnknown object = new IUnknownImpl(CLSID_MyClassDatabase, ClsCtx.ALL);
// Query the required interface from it
MyClassDatabaseImpl myClassInstance = new MyClassDatabaseImpl();
object.queryInterface(IID_ClassDatabase, myClassInstance);
// or even simpler
MyClassDatabaseImpl myClassInstance = new MyClassDatabaseImpl(object);
where CLSID_MyClassDatabase and IID_ClassDatabase are defined as following:
private final CLSID CLSID_MyClassDatabase = new CLSID("{use real CLSID in the following format 00000000-0000-0000-0000-000000000000}");
private final IID IID_ClassDatabase = new IID("{use real IID in the following format 00000000-0000-0000-0000-000000000000}");
But if your COM object supports automation, you can invoke its methods even without generated wrappers, using Automation technique. The following example demonstrates it:
// Initialize COM in the current Java thread
ComFunctions.coInitialize();
// Create COM object
IDispatch object = new IDispatchImpl(CLSID_MyClassDatabase, ClsCtx.ALL);
Automation automation = new Automation(object, true); // true means that the current thread will be used for methods invocation
automation.invoke("loadData");
...
Please find more information about ComfyJ in the following documents:
Tutorial - http://www.teamdev.com/downloads/comfyj/docs/ComfyJ-Tutorial.html
Programmer's Guide - http://www.teamdev.com/downloads/comfyj/docs/ComfyJ-PGuide.html
Message was edited by: Administrator
Thanks for the answer. That will definitely help me to focus somewhere else except only on jniwrapper.
Now i want to ask, I read the documentation for ComfyJ and it says that we need to tell GUID and Version number for the .DLL file to generate the Java Code. What if i don't know these?
Still waiting for response
Message was edited by: alee
Then you just need to run Codegen application (comfyj-2.3.zip\bin\CodegenForComfyJ.bat file) without parameters. It will start in UI mode and there you can select the required library from the list of the registered ones.
Please let me know if you have any further questions.
Thanks a lot Serge Piletsky for your kind help. I have gone through tutorials and able to generate the Com Java code.
There was a method in the given dll "connect()" which return HRESULT to check the status whether the connection established or not, but after generating the code through codegen, the method that have been generated does not have any return type. How can i check the status ?
after generating the methods, there is a method of generated java file which return BSTR String, how can i convert it in the Java String to use java classes on it?
Same is the case for Int32 Values, i am unable to compare the value returned by a function (Int32) in a for loop with an int variable.
Message was edited by: alee
1. As you may notice, all generated methods are declared as ones that "throws ComException". Such exception is thrown if a HResult of the function is not S_OK. Therefore, in order to get the status value you can use the following code:
try {
myClassInstance.connect();
} catch (ComException e) {
int status = e.getHResult();
...
}
2. The conversion of BStr to Java String is very simple. There is the BStr.getValue() method that returns a Java String. And of course you can set the Java String to BStr using the BStr.setValue(String value) method.
3. And for all integer parameters (such as Int32, LongInt, etc.) you can use the .getValue() method that returns Java long value, which in turns can be converted to the required type.
There are online Java Doc for both JNIWrapper and ComfyJ libraries. You can find them on Documentation page of each product.
-Serge
Message was edited by: Serge Piletsky