0

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

Valentina Chumak
  • 279
  • 6
  • 17
  • 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 Dec 14 '21 at 02:24
  • @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 Dec 14 '21 at 08:51
  • 1
    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 Dec 14 '21 at 11:36
  • It works! thanks a lot! But now I get ```java.nio.DirectByteBuffer[pos=0 lim=1 cap=1]``` as output of println. – Valentina Chumak Dec 14 '21 at 12:34
  • I looked into https://github.com/bytedeco/javacpp-presets/tree/helloworld/helloworld example but didn't understand the difference with mine – Valentina Chumak Dec 14 '21 at 13:09
  • 1
    Use BytePointer instead of ByteBuffer. It's not possible to have a ByteBuffer larger than 1 without knowing its size in advance. – Samuel Audet Dec 15 '21 at 01:08
  • 1
    I used this class in test and it works. System.out.println(greeter.hello(new BytePointer("world")).getString()); @SamuelAudet, thanks a lot!! – Valentina Chumak Dec 15 '21 at 08:08

0 Answers0