Chander Shivdasani
Chander Shivdasani

Reputation: 10121

Calling Java functions from C using 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.

Upvotes: 6

Views: 4421

Answers (3)

grep
grep

Reputation: 5623

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


        }

    }

Upvotes: 11

John O&#39;Hara
John O&#39;Hara

Reputation: 146

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

Upvotes: -4

Garrett Hall
Garrett Hall

Reputation: 30022

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

Upvotes: 2

Related Questions