B4J Question Link C program to B4j with JNI

marcopoilo

Member
Licensed User
I would like to link with JNI a very simple C program (print Hello and return 1) with B4j.

I have created the library mabibjni.dll with TestJNI0.c TestJNI0.h TestJNI0.def
I have created the TestJNI0.jar and TestJNI0.xml files with B4J_LibraryCompiler.exe from TestJNI0.java
I have put the library mabibjni.dll in the directory Objects of my B4J application JNItest.b4j

When I run the application JNItest.b4, the object s is created and the library mabibjni.dll is loaded. But after I have a java error when I use the method hello.
What is missing?
 

Attachments

  • JNIB4X.zip
    33.5 KB · Views: 244

marcopoilo

Member
Licensed User
Attached
 

Attachments

  • Image1.jpg
    Image1.jpg
    255 KB · Views: 208
Upvote 0

marcopoilo

Member
Licensed User
Waiting for debugger to connect...
Program started.
The library mabibjni.dll is loaded
java.lang.UnsatisfiedLinkError: b4x.testJNI.TestJNI0.hello()I
at b4x.testJNI.TestJNI0.hello(Native Method)
at b4j.example.main._appstart(main.java:88)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at b4j.example.main.start(main.java:38)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
java.lang.RuntimeException: java.lang.UnsatisfiedLinkError: b4x.testJNI.TestJNI0.hello()I
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:120)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at b4j.example.main.start(main.java:38)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.UnsatisfiedLinkError: b4x.testJNI.TestJNI0.hello()I
at b4x.testJNI.TestJNI0.hello(Native Method)
at b4j.example.main._appstart(main.java:88)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
... 12 more
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
(Untested) Try changing the C function signature (in both .c and .h files)

C:
JNIEXPORT jint JNICALL
Java_b4x_testJNI_TestJNI0_hello(JNIEnv *env, jobject obj) //<-- must include the java package name and class
{
  printf(" Hello\n ");
  return 1;
}
 
Upvote 0

marcopoilo

Member
Licensed User
Yes, yes it works thanks, but I had to change more in the .h (also lines ifndef and define).
Thanks.

#include <jni.h>
/* Header for class b4x_testJNI_TestJNI0 */

#ifndef _Included_b4x_testJNI_TestJNI0
#define _Included_b4x_testJNI_TestJNI0
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: b4x_testJNI_TestJNI0
* Method: hello
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_b4x_testJNI_TestJNI0_hello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Great!
I think that the #ifndef and #define changes in the .h are not needed (in fact you could put any string there, provided that they are equal), only the function signature. But you are right that the changes in the .def file are also necessary :)
 
Upvote 0
Top