Java C++ Wrapper for Android: how to wrap c++ templates - java

I'm working on an android project (a 3d realtime application) and would like to use a c++ library I've written. Since it's relying on templates I'm looking for a good solution to write a Java wrapper around it.
One idea I had, was to include the java class name in the JNI call when I create an object. For example I instantiate a Java class like this:
//java
A a = new A(Integer.class());
//jni call
if(strcmp("java.lang.integer", className) == 0) return (jlong) new A<int>();
else if(strcmp("java.lang.float", className) == 0) return (jlong) new A<float>();
else if( .... )
The problem with this solution is, that whenever I want to use a new data type I have to add another elseif code block and compile the c++ code again.

The problem with this solution is, that whenever I want to use a new data type I have to add another elseif code block.
Remember that there are only 8 primitive types in Java. If you add one if-else for each of those, you will be able to handle any primitive type argument.
If you also add a case for jobject you can also use that to handle any object type. Just be careful to handle your JNI object references correctly.

Related

Pass C++ object to Java vs set object parameters one by one using JNI

I have searched for this question and found a few answers but have not really found what I am looking for.
I call Java using JNI from C++ and set a Java object's fields one by one. Something like below:
jobject jSomeObject = (jobject) JVM_ENV->CallObjectMethod(myObj, getObjMethodID, "");
JVM_ENV->CallVoidMethod(jSomeObject , setMethodID1, SomeIntVal);
JVM_ENV->CallVoidMethod(jSomeObject , setMethodID2, SomeStringVal);
All parameters inside the jSomeObject are set one by one like this. And you see that there are multiple JNI calls going on which is expensive. What I am thinking is, if there is a way that I set all the parameters in the native environment and send the object just once to avoid multiple JNI calls.
Some of the posts says that it is not possible to pass a custom object to JNI. Can I do it ?
Edit:
Above calls changed to something:
jobject jSomeObject = (jobject) JVM_ENV->CallObjectMethod(myObj, getObjMethodID, "");
someClass obj = new someClass();
obj.setMethod1(someInvVal);
obj.setMethod2(someStringVal); // so on...
JVM_ENV->CallVoidMethod(jSomeObject , setMethodID1, obj);
No: You can only call methods and constructors and get and set fields that are defined in Java.
Yes: You can possibly define additional classes and methods in Java that will do what you need in one call. For example, myObj:getObjMethodID seems to be a factory method. You could add a method overload that takes all the values you want to initialize the created object with.
In general, if you can make things powerful in Java, the tasks done in JNI will be simpler.

Delphi to Java (biometrics)

I'm developing a tool for recognition biometric and I'm using the provided SDK (*.dll), developed in Delphi.
For the access at dll, I'm using JNA.
The template of the digital (the most important part) is an object which refers to this passage(in Delphi):
type
CIS_Digital = packed record
intSize: integer;
pDigital: Pointer
end;
pCIS_Digital = ^CIS_Digital;
How to develop something equivalent in Java?
Thanks.
Basically, the following call DLL functions:
SDK_CIS_Iniciar(int cnpj, int detectaFake);
SDK_CIS_LerDigital(pCIS_Digital digital);
SDK_CIS_CompararDigital(pCIS_Digital sample1, pCIS_Digital sample2);
SDK_CIS_Finalizar ();
Looking at the example provided, developed in Delphi, I saw that the pCIS_Digital object, which is passed on SDK_CIS_LerDigital () and SDK_CIS_CompararDigital () references the code snippet:
type
CIS_Digital = packed record
intSize: integer;
pDigital: Pointer
end;
pCIS_Digital = ^CIS_Digital;
In the example developed in Delphi, before calling the SDK_CIS_LerDigital () method, the pCIS_Digital object is instantiated.
That is, it (the object parameter) will emptiness and is "filled" by function.
The reader is TechMag BioFlex (http://www.techmag.com.br/bioflex/), which is based on Futronic readers (SF-80).
Searching, I saw that the pCIS_Digital object (code snippet), makes memory access to read the information that the reader writes it writes.
After much research, I think I should develop an equivalent object in Java, extending the Structure or Memory class, of the JNA.

Dynamic return type - Java Generics

I have a two similar objects (actually entities). From a function, I get either one of them. So I know which one I got only during the runtime.
I need to do processing on the object I got. Both have same set of processes to be applied. So I would like to write Generic function both both these classes. I tried to write, but I did not get clear idea how to implement this.
List<MyClassA> objAList;
List<MyClassB> objBList:
List<ResultA> resultObjAList;
List<ResultB> resultObjBList;
objAList = getResult();
objBList = getResult()
if ( objAList != null ) {
// Set of function calls on ObjA to process further. For ex:
resultObjAList = doProcess(objAList);
} else {
// Same set of function class to process. For Ex:
resultObjBList = doProcess(objBList);
}
I am about to decide to write two different functions that look similar to do the processing for each of these classes, after a few attempts.
Note the doProcess function above. It takes the objA or objB and return resultObjA or resultObjB.
I cannot wrap both of these with an interface. So option is ruled out.
doProcess looks like this:
List<ResultA> doProcess( List<MyClassA> A ) {
for ( MyClassList a : A ) {
a.getSomething();
doanotherProcess(a.getxya(), a.getABC());
....
}
return AnotherListOfType_ResultA;
}
Is it possible to write generic function for this?
If you want to generically map a List<MyClassA> input to ResultA and List<MyClassB> input to ResultB, then I can answer that this is not possible: there is no way to express with Java Generics that kind of dependency of result type on input type.
Theoretically, you could parameterize MyClassA with ResultA, as in MyClassA<ResultA>, but it would probably just make a mess out of your code.
Even if you want to write two functions like
public void doProcess(List<ObjectA> list); and
public void doProcess(List<ObjectB> list); it is not possible, because generics are compile time constructs only, hence the both functions have same erasure.
The best you can do is have a function and cast your object based on some condition.

C++ NEW Object as parameter (Like Java)

I'm coding some stuff in C++, and as always we have some "thoughts" if something similar exists on the language...
I'm now, with an doubt about objects passing as parameters.
What I always do, is create a new object, and pass it's instance as a pointer, like this:
mObject* obj1 = new mObject();
obj1->callback(the_callback_function);
function_that_needs_obj(obj1); // (or the reference, if I didn't instantiated a pointer).
That's OK, works OK, there is no problem with this. But, as I used Java, I used to do like this:
function_that_needs_obj(new mObject(){
public void onCallback(){
// Custom code enters here....
}
});
Is there any "sort" of use in C++ like this? Because for EACH callback that I need to create: One Extended class, or, one functionNamedVeryLongBecauseThereAreMany must be written on TOP of the code, and that kind of "confuses" a lot the code...
And also, all Object variable, are not accessible trough this if I assing an FUNCTION callback...
if you compiler support c++11, you can use lambda expression like this:
function_that_needs_obj([]()
{
// Custom code enters here....
});
What is a lambda expression in C++11?
You could find what you need in boost lambda!

Method of binding Java functions to Lua?

I'm working on a Lua wrapper for my Android app, which will allow me to write Lua code to speed up development. I've made a static class called lua with functions like newState and pushString. I manage the Lua state by passing around a long with the pointer to the lua_State. As you can tell, I don't need any fancy stuff that makes interaction easier, like overloads to push variables.
Now, the problem is binding Java functions to Lua variables. I've thought of a few ways to do this, but they're all ugly.
Instead of functions, pass around a table with a reference to the Java function as a userdatum and have a __call metamethod take care of calling the "function".
Alter Lua internals to include a Java reference with Lua C functions.
Is there any better way to go about this? Or should I go with the second method? (I realise the first method is ridiculous, but it manifested itself in my mind as a solution anyways.)
You can have a look at my simple project AndroLua. It contains Lua and LuaJava compiled using the Android NDK.
Because it uses LuaJava, it allows to bind Java functions to Lua, in a similar way like you said, using userdata. Here is an example of how I override the print function to output text into a TextView:
JavaFunction print = new JavaFunction(L) {
#Override
public int execute() throws LuaException {
StringBuilder sb = new StringBuilder();
for (int i = 2; i <= L.getTop(); i++) {
int type = L.type(i);
String val = L.toString(i);
if (val == null)
val = L.typeName(type);
sb.append(val);
sb.append("\t");
}
sb.append("\n");
status.append(sb.toString());
return 0;
}
};
print.register("print");
The downside is that sometimes you cannot pass the print as a function parameter (because it is a userdata, even though it has a __call metamethod). Fortunately, it can be solved in Lua by creating a pure Lua function, like this:
do
local oldprint = print
function print(...) oldprint(...) end
end
I decided to use lua_pushcclosure, as it allows you to 'store' arbitrary values on functions that can be retrieved with the lua_upvalueindex macro.
There is also Kahlua vs LuaJava.
It is mentioned in this book: http://books.google.com/books?id=2v55tfq9rosC&lpg=PA166&ots=9RRVaz5JjP&dq=krka%20kahlua%20blog&pg=PA166#v=onepage&q&f=false
The development blog:
http://krkadev.blogspot.com/2010/05/getting-started-with-kahlua2.html

Categories

Resources