2012-04-02 178 views
3

我在阅读Java Native Access,并且到目前为止,我已经能够成功地从Java调用C函数。使用JNA从C调用Java函数

有没有办法做相反的事情?谷歌搜索没有多大帮助。

+1

使用JNI,你可以两种方式。我不知道JNA。 – Vincent 2012-04-02 21:17:06

+0

是的,你可以。请参阅我的回答 – grep 2016-01-14 11:46:01

回答

-1

这并不与JNA工作,使用JNI来代替http://en.wikipedia.org/wiki/Java_Native_Interface

+1

不正确。 JNA有可能。我自己尝试过,并且工作。 – diarmuid 2014-05-04 22:52:19

+0

如果有人感兴趣,有Java/C代码:基本上在C函数指针,然后JNAerator做所有的魔术...... – diarmuid 2014-05-04 23:07:44

1

看起来像你可以start the JVM and call functions in Java from C,使用JNI库。这是你在追求什么?

+0

我基本上想知道是否有一种方法可以使用JNA来实现。我试过用JNI,它的工作原理。这只是探索JNA的乐趣 – 2012-04-02 21:41:07

+0

是的,你可以使用JNA。你可以看到我的例子: – grep 2016-01-14 11:50:29

+0

http://stackoverflow.com/a/34788835/2590960 – grep 2016-01-14 11:50:35

5

当然,你也可以!我们来创建一个简单的例子

让我们创建头文件header.h。对于回调,我们将使用callbackTriger方法。 getDeviceRandomStatus和randNum只是用于生成随机数据响应的辅助方法。

#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测试库方法:

#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; 
} 

现在,让我们创建共享库并对其进行测试:

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 

现在我们需要JAVA类了!走吧:

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


     } 

    }