Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Java functions from C using JNA

Tags:

java

jna

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.

like image 376
Chander Shivdasani Avatar asked Apr 02 '12 21:04

Chander Shivdasani


1 Answers

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);


        }

    }
like image 82
grep Avatar answered Sep 30 '22 03:09

grep