C++ Function with pointer as parameter and Handle it with swig interface - java

I have created swig interface file to create JNI for my C++ Files. but some of my C++ Files include functions which accept pointer as argument like (void*) , C++ BOOL and Swig converts it into
type like SWIGTYPE_p_int32_t how to pass such kind of data type from java ?
for example one of the function's actual prototype is like below in C++
DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE));
which is converted in Java file with swig
public static void FreeImage_Initialise(SWIGTYPE_p_int32_t load_local_plugins_only)
how to pass such value from java ?
I have many classes which include such kind of arguments in function.
is there any way so that I can apply solution to bulk files for handle datatype as simple as possible.
I have read one way to do that is create helper function but I cannot go for it because i have many c++ classes and for each and every function creating helper function for returning pointer is not way to go.
Please suggest any other way if possible.

Solved myself. Swig was not be able to recognize all the typedef in header files and hence it was producing that kind of Types in wrapper. I need to redefine them in Interface file.

About booleans, I would recommend using boolinstead of BOOL because JNI directly provides a type signature for it: Z (you can check signatures at: JNI Types and Data Structures)
About pointers, if are pointer to basic types, this is declared by adding [in front of corresponding signature, this is: int* --> [I. If it's a pointer to a own class, swig will create a fully qualified class.
Hope this helps.

This is because of the weird declaration of BOOL type.
In this particular case, you can pass an int there from Java side. Either 0 or 1 will do the right job.
Or you can change BOOL to bool in your native code by creating a small wrapper for this library.

SWIG doesn't know about windows types. Add %include <windows.i> to the interface definition.

Related

How to pass List<T> from Java to a C++ std::vector function parameter using JNA

I have a native function :
int NativeFunction(std::vector<MyObject>);
I am loading the Native dll using JNA and I am trying to call this function NativeFunction from Java like:
nativedlljnapointer.NativeFunction(List<MyObject>);
I am however running into "java.lang.IllegalArgumentException: Unsupported argument type ArrayList" exception.
I al tried using java util vector when I am running into the same exception "java.lang.IllegalArgumentException: Unsupported argument type java.util.Vector"
Can someone suggest me how I could pass List from my Java function to the native function which has vector<> as an argument.
Any help will be greatly appreciated.
std::vector and java List are completely different types, it's normal for them not to work.
Furthermore , Is MyObject a C++ defined object or a Java defined object (if you define one in each, they are again, completely different objects ! )?
The best and safest way to communicate via JNI is to use serialization, like you would between any two different environments.
Granted, it takes a bit of extra work, but in the long run you end up with more robust code.

Swig generted class in swig interface file

I'm using SWIG to generated Java classes and I have 3 different classes that one dependant on the others.
SWIG makes pointers to this classes because it didn't know about it, I need that SWIG uses the Java classes that created and not the pointers that SWIG creates.
How can I do this?
I have c++ function like this:
bool foo(class1& parm);
Now I use SWIG to create class1 in Java and I want to make SWIG to wrap foo in Java with the parameter class1 that it created and not SWIG_P_class1. I don't have any way to do this.
Swig hides away details like the actual classes or objects used. If you want to access the real Java objects and class I suggest you use JNI (which gives you access to everything and is likely to be faster)
For types that SWIG knows nothing about (i.e. hasn't seen anything more than a forward declaration) the best wrapper it can generate roughly mirrors what you can do with a forward declared class in C++ - it gets wrapped as something that behaves like an opaque pointer. This is the SWIG_P_class1 you're seeing. You can do sensible things with this, e.g. if you have a method that returns references or pointers to instances you could call that to get an object to pass to foo.
However you probably don't want to use that much in real interfaces, so given a header file we want to wrap that looks like:
class class1;
bool foo(class1& parm);
You can wrap it sensibly by giving SWIG a partial (or complete if you prefer) definition of the class1, e.g.:
%module test
class class1 {
};
%include "test.hh"
will cause a sensible class1 and foo to be exposed on the Java side, so you could use them in Java as in:
test.foo(new class1());
exactly as you'd hope.
You will of course need to provide the generated C++ sufficient knowledge of the class1 class, exactly as you would with any other C++ code. The easiest way to do that is to make your SWIG interface look something like:
%module test
%{
#include "class1_defined_here.hh"
%}
class class1 {
};
%include "test.hh"

Calling DLL with a C interface from Java

I'm attempting to call native methods within a 3rd party DLL, which has a C interface with methods such as:
DWORD ExampleInterfaceMethod( DWORD Mode, LPSTR Header );
I've successfully loaded the DLL using:
System.loadLibrary("DLLName");
and I've created a method:
protected native int ExampleInterfaceMethod(int type, int Nth, byte[] name);
This method doesn't seem to be using the correct variable types, as whenever I call it the following error is thrown: java.lang.UnsatisfiedLinkError: com.DLLTest.ExampleInterfaceMethod(II[B)I
What variable types do I need to use in Java in order to call this method, or am I missing something else?
With JNI, you need specially-named C functions to implement your Java native methods. You can't simply add a native method to call an existing C function - instead the normal way is creating a "wrapper" C function which calls the existing one, and is named the right way.
You might want to have a look at JNA. This is a wrapper around JNI which allows you to call C functions from the Java side without manually writing adapting native code for this.

How to declare and call a native method containing pointers in java

How to declare and call a native method in c containing pointers using java?
please it is urgent.Because there is no concept of pointers in java i am getting error.
Use JNI(Java Native Interfaces) to call native methods in java. Use this JNI specification pdf as a reference "java.sun.com/docs/books/jni/download/jni.pdf".
There is even a easier approach to the subject, if you or your boss are willing to pay 50$!
Is called eXcelsior xFunction. Try the evaluation version.
Works very well and is simple to use.
The only thing xFunction library does not do have is implementation of address arithmetic in Java, which i assume you will possibly never need.
From their site:
With xFunction, you no longer need to implement those ugly native methods. Instead, you extend and instantiate xFunction classes to create conventional Java objects representing external functions, data structures, pointers, and callbacks. All necessary data conversions and external function calls are done seamlessly by the xFunction library:
import com.excelsior.xFunction.*;
...
/* Call Beep() from KERNEL32.DLL */
xFunction f =
new xFunction( "kernel32",
"int Beep(int,int)" );
f.invoke( new Argument(1770),
new Argument(100) );

Swig: convert return type std::string to java byte[]

I have a C++ method that returns a std::string. I am using SWIG and I want to add logic to SWIG to make the std::string that is returned, be received in Java as a byte[].
If this is possible, how can I do this?
Thanks
SWIG comes with pre-written interface files for many C++ constructs. The are found in SWIG's Lib directory for many languages, including Java.
Add %include <std_string.i> in your SWIG interface file. Check SWIG's Lib/Java directory for support for other constructs as well.
std::string has a member function c_str that does essentially that. It would probably make sense to write a wrapper function that calls your function and returns the corresponding c string.

Categories

Resources