C-DLL中的回调函数转换为Java JNA

问题描述 投票:0回答:1

我在使用JNA将回调函数从C-DLL映射/转换为Java时遇到问题。

在编写回调函数后的C头文件上:

// ! callback function header whenever a data report is received from a device
typedef void (FR_callback_func)(Data_t frame);

以上Data_t的结构如下:

// ! Carries information about one signal.
typedef struct
{
    unsigned char index;
    int isval;
    unsigned short val;
    int arr_Length;
    unsigned char array[8];
} Data_t ;

[Data_t结构被调用的函数:

int getData(int val,Data_t *data);

现在,我将我的JAVA代码翻译如下:

public interface device extends Library 
{
    public interface FR_callback_func extends Callback
    {
        void invoke(Data_t signal);
    }

    public class Data_t extends Structure implements com.sun.jna.Structure.ByReference 
    {
        public static class ByReference extends Data_t implements Structure.ByReference { }
        public byte index;
        public int isval;
        public  short val;
        public int arr_Length;
        public byte[] array = new byte[8];
        @Override
        protected java.util.List<java.lang.String> getFieldOrder()
        {    
            return Arrays.asList(new String[] {"index","isval","val","arr_Length","array"});
        }
    } 

    public int getData (int val,Data_t.ByReference data);
}

然后我尝试在主要功能中使用它,如下所示:

public static void main(String[] args) throws IOException 
{
    Data_t .ByReference data_t = new Data_t .ByReference();
    int data = 0;
    int val = 0;

    device h = (device) Native.load("Library", device.class);

    data = h.getData (val, data_t);
}

我的问题是我是否正确翻译了上面的C代码?特别是回调函数?由于C代码无法操作。因此,我必须在JAVA中翻译提供的C-DLL代码。

您的建议将不胜感激。

java c eclipse dll dynamic-dll-import
1个回答
0
投票

没有在上面粗略记录您仍然缺少的所需位:

  • C示​​例库
// gcc -c -Wall -Werror -fPIC foo.c
// gcc -shared -o libfoo.so foo.o

#include <stdio.h>

typedef struct {
  int x;
  int y;
} Foo;

typedef Foo* (*FooCallback)(int, int);

void printFoo(Foo *foo) {
  printf("foo: %p x: %d y: %d\n", foo, foo->x, foo->y);
}

FooCallback callback = NULL;

void setCallback(FooCallback cb) {
  callback = cb;
}

void runCallback() {
  if (callback) {
    Foo *foo = callback(123, 456);
    printf("foo from callback: %p x: %d y: %d\n", foo, foo->x, foo->y);
  } else {
    printf("callback not set!\n");
  }
}
  • java示例代码
// javac -classpath .:jna.jar Foo.java 
// java -classpath .:jna.jar Foo

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Callback;


public class Foo {
  public interface CFoo extends Library {
    public class SFoo extends Structure {
      public static class ByReference extends SFoo implements Structure.ByReference { }
      public static class ByValue extends SFoo implements Structure.ByValue { }
      public int x;
      public int y;
    }

    void printFoo(SFoo foo);

    public interface FooCallback extends Callback {
      SFoo invoke(int x, int y);
    }

    void setCallback(FooCallback cb);
    void runCallback();
  }

  public static void main(String[] args) {
    CFoo cfoo = (CFoo) Native.loadLibrary("libfoo.so", CFoo.class);

    // test construction of SFoo
    CFoo.SFoo foo = new CFoo.SFoo();
    foo.x = 23;
    foo.y = 42;

    // test auto ByReference
    System.out.println("foo pointer: " + foo.getPointer());
    cfoo.printFoo(foo);

    // callback test
    // no callback set yet
    cfoo.runCallback();

    // set callback
    CFoo.SFoo foo2 = new CFoo.SFoo();   // declare outside to "survive" callback scope
    CFoo.FooCallback cb = new CFoo.FooCallback() {
      public CFoo.SFoo invoke(int x, int y) {
        System.out.println("values from C x: " + x + " y: " + y);
        // CFoo.SFoo foo2 = new CFoo.SFoo(); <--- never do this here!
        foo2.x = x;
        foo2.y = y;
        foo2.write();   // explicitly write to memory needed here
        return foo2;
      }
    };
    cfoo.setCallback(cb);

    // rerun with set callback
    cfoo.runCallback();

    // avoid gc for cb and foo2
    assert cb != null : "Oops";
    assert foo2 != null : "Oops";
  }
}

请注意,如果有回调esp,GC需要特别注意。非原始数据类型。因此,我在示例中放置了一个将结构本身返回给C(foo2)的回调。该对象必须在处理它的C代码中保留下来,否则它将发生段错误。

如果不清楚,请提出,因此我可以将其添加到示例中。希望这会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.