Calling Java functions from C using JNA

I am 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 didn't help much.

+3


source to share


3 answers


This doesn't work with JNA, use JNI instead http://en.wikipedia.org/wiki/Java_Native_Interface



-1


source


Of course you can! Let's create a simple example.

create header file header.h . For the callback, we will use the callbackTriger method. getDeviceRandomStatus and randNum are just helper methods for generating random data.

#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 let's create a 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 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);


        }

    }

      

+5


source


It looks like you can start the JVM and call functions in Java from C using the JNI library. Is this what you are after?

+1


source







All Articles