tarzanking / javacpp

Automatically exported from code.google.com/p/javacpp
GNU General Public License v2.0
0 stars 0 forks source link

problem when using an array of char* as parameter #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. on eclipse, create an android class using this C dummy signature:
public int callBtSco(int argc, char* argv[]);
2. use the java command line to generate the library for android
3.

What is the expected output? What do you see instead?
The java command line completes successfully but eclipse can not compile the 
class because of "char*". 

If I replace it with:
public native int callBtSco(int argc, CharPointer[] argv); 
The java command line fails:
fabien@dell-debian:~/workspace/btScoTest$ java  -jar libs/javacpp.jar 
-classpath bin/ -classpath bin/classes/ 
-Djava.library.path=/home/fabien/workspace/btScoTest/libs/armeabi -properties 
android-arm  -Dplatform.root=/home/fabien/android/android-ndk-r7  
-Dcompiler.path=/home/fabien/android/android-ndk-r7/toolchains/arm-linux-android
eabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ 
com.test.btsco.BtSco 
Generating source file: 
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp
Building library file: 
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/android-arm/libjniBt
Sco.so
/home/fabien/android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebu
ilt/linux-x86/bin/arm-linux-androideabi-g++ 
--sysroot=/home/fabien/android/android-ndk-r7/platforms/android-9/arch-arm/ 
-I/usr/lib/jvm/java-6-openjdk/include 
-I/usr/lib/jvm/java-6-openjdk/include/linux 
-I/home/fabien/android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include/ 
-I/home/fabien/android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi
/include/ 
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp 
-march=armv5te -mtune=xscale -msoft-float -Wl,-rpath,lib/ -DANDROID 
-ffunction-sections -funwind-tables -fstack-protector -funswitch-loops 
-finline-limit=300 -Wall -O3 -nodefaultlibs -fPIC -shared 
-Wl,--no-allow-shlib-undefined -s -o 
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/android-arm/libjniBt
Sco.so 
-L/home/fabien/android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi
/ -llog -lgnustl_static -lgcc -ldl -lz -lm -lc 
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp: In 
function 'jint Java_com_test_btsco_BtSco_00024BtScoClass_callBtSco(JNIEnv*, 
_jobject*, jint, _jobjectArray*)':
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp:747: 
error: 'pointer1' was not declared in this scope
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp:747: 
error: 'struct JNIEnv_' has no member named 'GetCom'
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp:750: 
error: 'class BtSco::BtScoClass' has no member named 'callBtSco'
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp:752: 
error: 'struct JNIEnv_' has no member named 'ReleaseCom'

What version of the product are you using? On what operating system?
I'm using javacpp-bin-20120218.zip on debian/unstable.

Please provide any additional information below.

This is the corresponding method.
JNIEXPORT jint JNICALL 
Java_com_test_btsco_BtSco_00024BtScoClass_callBtSco(JNIEnv* e, jobject o, jint 
p0, jobjectArray p1) {
    BtSco::BtScoClass* pointer = (BtSco::BtScoClass*)jlong_to_ptr(e->GetLongField(o, JavaCPP_addressFieldID));
    if (pointer == NULL) {
        e->ThrowNew(JavaCPP_getClass(e, 1), "This pointer address is NULL.");
        return 0;
    }
    jint position = e->GetIntField(o, JavaCPP_positionFieldID);
    pointer += position;
     pointer1 = p1 == NULL ? NULL : e->GetCom.googlecode.javacpp.CharPointerArrayElements(p1, NULL);
    jint r = 0;
    try {
        int rvalue = pointer->callBtSco(p0, pointer1);
        r = (jint)rvalue;
        if (p1 != NULL) e->ReleaseCom.googlecode.javacpp.CharPointerArrayElements(p1, pointer1, 0);
    } catch (...) {
        JavaCPP_handleException(e);
    }
    return r;
}

Original issue reported on code.google.com by theedge...@gmail.com on 24 Feb 2012 at 3:19

GoogleCodeExporter commented 9 years ago
Could you try again with
    public native int callBtSco(int argc, PointerPointer argv); 
?

Original comment by samuel.a...@gmail.com on 25 Feb 2012 at 1:16

GoogleCodeExporter commented 9 years ago
It's better but it still fails because of my Java code.
I'm not used to manipulate generic parameters.
<code>
public native int callBtSco(int argc, PointerPointer argv);
       public void start()
       {
           String l_param1 = new String("-vr");
           String l_param2 = new String("00:01:02:03:04:05");
           char[] l_argv1 = l_param1.toCharArray();
           char[] l_argv2 = l_param2.toCharArray();
           PointerPointer l_argv = new PointerPointer(l_argv1, l_argv2);
           callBtSco(2, l_argv);
       }
</code>
<error>
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp: In 
function 'jint Java_com_test_btsco_BtSco_00024BtScoClass_callBtSco(JNIEnv*, 
_jobject*, jint, _jobject*)':
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp:752: 
error: invalid conversion from 'void**' to 'char**'
/home/fabien/workspace/btScoTest/bin/classes/com/test/btsco/jniBtSco.cpp:752: 
error:   initializing argument 2 of 'int BtSco::BtScoClass::callBtSco(int, 
char**)'
</error>
<jniCode>
JNIEXPORT jint JNICALL 
Java_com_test_btsco_BtSco_00024BtScoClass_callBtSco(JNIEnv* e, jobject o, jint 
p0, jobject p1) {
    BtSco::BtScoClass* pointer = (BtSco::BtScoClass*)jlong_to_ptr(e->GetLongField(o, JavaCPP_addressFieldID));
    if (pointer == NULL) {
        e->ThrowNew(JavaCPP_getClass(e, 1), "This pointer address is NULL.");
        return 0;
    }
    jint position = e->GetIntField(o, JavaCPP_positionFieldID);
    pointer += position;
    void** pointer1 = p1 == NULL ? NULL : (void**)jlong_to_ptr(e->GetLongField(p1, JavaCPP_addressFieldID));
    jint position1 = p1 == NULL ? 0 : e->GetIntField(p1, JavaCPP_positionFieldID);
    pointer1 += position1;
    jint r = 0;
    try {
        int rvalue = pointer->callBtSco(p0, pointer1);
        r = (jint)rvalue;
    } catch (...) {
        JavaCPP_handleException(e);
    }
    return r;
}
</jniCode>

Original comment by theedge...@gmail.com on 27 Feb 2012 at 2:38

GoogleCodeExporter commented 9 years ago
Right, we need an explicit cast:
    public native int callBtSco(int argc, @Cast("char**") PointerPointer argv);
And to build a valid PointerPointer for that use case, we can do something like 
this:
    PointerPointer l_argv = new PointerPointer(new BytePointer(l_param1), new BytePointer(l_param2));
If you need something else than UTF-8, use the other BytePointer constructor to 
specify the required character encoding.

Original comment by samuel.a...@gmail.com on 28 Feb 2012 at 3:08

GoogleCodeExporter commented 9 years ago
Thanks Samuel,

It compiles.
Now I have the issue "library not found".
I'll post it on the forum.
You can close this issue.

Original comment by theedge...@gmail.com on 28 Feb 2012 at 3:47

GoogleCodeExporter commented 9 years ago
It it does not sound like a bug, please post your question on the mailing list 
if possible, thank you!

I will keep this issue opened and fix the incorrectly generated code above... 
it should give us a warning instead.

Original comment by samuel.a...@gmail.com on 29 Feb 2012 at 2:43

GoogleCodeExporter commented 9 years ago
BTW, I haven't seen any message on the forum asking about the "library not 
found" problem, have you solved it?

In any case, latest release now properly outputs a warning instead of 
generating incorrect code for non-primitive arrays. Thanks for the feedback!

Original comment by samuel.a...@gmail.com on 3 Mar 2012 at 4:49

GoogleCodeExporter commented 9 years ago
I think I have problems with the NDK compiler.
I'll get back when I clarify things.
Thanks for the fix.

Original comment by theedge...@gmail.com on 3 Mar 2012 at 9:49