0
votes

I'm trying to use javacpp library. I've prepared c-lib with one function

char * hello(const char * name);

and build it with cmake (on mac, with clang++)

Also I've prepared config file for javacpp

package arrival;

import org.bytedeco.javacpp.annotation.*;
import org.bytedeco.javacpp.tools.*;

@Properties(
        value = @Platform(
                includepath = {"/Users/valentina.baranova/external/kotlin-cloud/greeter/include/"},
                include = {"greeter.h"},
                library = "greeter-jni",
                link = {"greeter"},
                linkpath = {"/Users/valentina.baranova/external/kotlin-cloud/greeter/build/"}
        ),
        target = "arrival.greeter"
)
public class GreeterConfig implements InfoMapper {
    public void map(InfoMap infoMap) {
    }
}

javacpp prepared library libgreeter-jni.dylib, but when I try to call hello function I got an error

dlopen(/Users/valentina.baranova/external/kotlin-cloud/greeter-javacpp/target/classes/arrival/macosx-x86_64/libgreeter-jni.dylib, 0x0001): symbol not found in flat namespace '__Z5helloPKc'

What I'm doing wrong? In debug I see that Loader.load() loads both libraries.

UPD: Loader.load() is loaded in autogenerated greeter class.

Function hello there is in both libraries but it has different name

nm libgreeter-jni.dylib | grep hello
0000000000001f70 T _Java_arrival_greeter_hello__Ljava_lang_String_2
0000000000001ce0 T _Java_arrival_greeter_hello__Lorg_bytedeco_javacpp_BytePointer_2
                 U __Z5helloPKc
nm libgreeter.dylib | grep hello
0000000000003f50 T _hello

enter image description here

If you're not calling Loader.load() anywhere, that would cause that. It's probably not getting called on your class. Also make sure that the symbol is actually in your library. You can use tools like nm to see them.Samuel Audet
@SamuelAudet There is such function but it has different name ``` nm libgreeter-jni.dylib | grep hello 0000000000001f70 T _Java_arrival_greeter_hello__Ljava_lang_String_2 0000000000001ce0 T _Java_arrival_greeter_hello__Lorg_bytedeco_javacpp_BytePointer_2 U __Z5helloPKc ``` ``` nm libgreeter.dylib | grep hello 0000000000003f50 T _hello ```Valentina Chumak
It looks like that function was compiled with a C compiler, not a C++ compiler. In that case, replace @Platform(..., include = {"greeter.h"}, ...) with @Platform(..., cinclude = {"greeter.h"}, ...).Samuel Audet
Use BytePointer instead of ByteBuffer. It's not possible to have a ByteBuffer larger than 1 without knowing its size in advance.Samuel Audet
I used this class in test and it works. System.out.println(greeter.hello(new BytePointer("world")).getString()); @SamuelAudet, thanks a lot!!Valentina Chumak