I'm reading about Java Native Access and so far i have been able to successfully call C functions from Java.
Is there a way to do the opposite? Googling didnt help much.
Off course you can! Let's create simple example.
let's create header file header.h. For callback we will use callbackTriger method. getDeviceRandomStatus and randNum is just helper methods to generate random data responses.
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
typedef void(*NotificationListener)(char *, int);
void callbackTriger(const NotificationListener l);
void getDeviceRandomStatus(char *answer, int sizeOfChars);
int randNum( int min, int max);
#endif // HEADER_H_INCLUDED
header.c
#include<stdio.h>
#include "header.h"
#include <stdlib.h>
#include <time.h>
void callbackTriger(const NotificationListener l){
int size=randNum(1,20);
char answer[size];
getDeviceRandomStatus(answer, size);
(*l)(answer, sizeof(answer));
}
void getDeviceRandomStatus(char *answer, int sizeOfChars){
int i;
for(i=0; i<sizeOfChars; i++){
int i=randNum(0,255);
answer[i]=i+'0';
}
}
int randNum( int min, int max){
srand ( time(NULL) );
double scaled = (double)rand()/RAND_MAX;
int val=(max - min +1)*scaled + min;
return val;
}
main.c for testing library methods:
#include<stdio.h>
#include <limits.h>
#include <stdlib.h>
int main(void)
{
int sizeOfChars=randNum(1,10);
char answer[sizeOfChars];
getDeviceRandomStatus(answer, sizeOfChars);
int i;
for (i = 0; i < sizeof(answer); ++i){
printf("%d ", answer[i]);
}
return 0;
}
Now lets create Shared lib and test it:
cd <path>
gcc -c -Wall -Werror -fpic header.c
gcc -shared -o libHeader.so header.o
gcc main.c -o main -lHeader -L<path> -Wl,-rpath=/home/vq/Desktop
./main
Now we need JAVA classes! Let's go:
import java.util.Arrays;
import java.util.logging.Logger;
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
public class CallBack {
public static Logger log = Logger.getLogger(CallBack.class.getSimpleName());
public interface CLibrary extends Library {
public interface NotificationListener extends Callback {
void invoke(Pointer val, int lenth);
}
public static class NotificationListenerImpl implements NotificationListener {
@Override
public void invoke(Pointer val, int lenth) {
log.info("returned byte array, size: "+lenth);
log.info("java mehtod, callback: " + Arrays.toString(val.getByteArray(0, lenth)));
}
}
public void callbackTriger(NotificationListener callback);
}
static public void main(String argv[]) {
CLibrary clib = (CLibrary) Native.loadLibrary("<path>/libHeader.so", CLibrary.class);
// instantiate a callback wrapper instance
CLibrary.NotificationListenerImpl callbackImpl = new CLibrary.NotificationListenerImpl();
// pass the callback wrapper to the C library
clib.callbackTriger(callbackImpl);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With