Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JNR采用指针参数的回调/闭包_Java_C_Jnr - Fatal编程技术网

Java JNR采用指针参数的回调/闭包

Java JNR采用指针参数的回调/闭包,java,c,jnr,Java,C,Jnr,我正在使用JNR并尝试传递具有以下C等效签名的回调函数: int fn(void const*, void const**, void**) 转换成一些C函数。我已将嵌套在Java端JNR库接口中的回调声明为: public static interface Fn { @Delegate public int call(Pointer a, Pointer[] b, Pointer[] c); } 使用JNR库接口中的另一个函数 public int doSomething(Fn fn)

我正在使用JNR并尝试传递具有以下C等效签名的回调函数:

int fn(void const*, void const**, void**)
转换成一些C函数。我已将嵌套在Java端JNR库接口中的回调声明为:

public static interface Fn {
  @Delegate public int call(Pointer a, Pointer[] b, Pointer[] c);
}
使用JNR库接口中的另一个函数

public int doSomething(Fn fn);
在C代码中充当
doSomething
的包装,接受
int(*)(void const*,void const**,void**)
。但每当我创建回调时:

new Fn() { int call() { ... } };
并将其传递给JNR库接口的
doSomething
方法,我得到运行时错误:

java.lang.ExceptionInInitializerError

    Caused by:
    java.lang.IllegalArgumentException: unsupported closure parameter type class [Ljnr.ffi.Pointer;
        at jnr.ffi.provider.jffi.NativeClosureProxy.newProxyFactory(NativeClosureProxy.java:109)
        at jnr.ffi.provider.jffi.NativeClosureFactory.newClosureFactory(NativeClosureFactory.java:84)
        at jnr.ffi.provider.jffi.NativeClosureManager.initClosureFactory(NativeClosureManager.java:71)
        at jnr.ffi.provider.jffi.NativeClosureManager.getClosureFactory(NativeClosureManager.java:49)
        at jnr.ffi.provider.jffi.NativeClosureManager.newClosureSite(NativeClosureManager.java:81)
        at jnr.ffi.provider.jffi.InvokerTypeMapper.getToNativeConverter(InvokerTypeMapper.java:68)
        at jnr.ffi.provider.jffi.InvokerTypeMapper.getToNativeType(InvokerTypeMapper.java:143)
        at jnr.ffi.mapper.CachingTypeMapper.lookupAndCacheToNativeType(CachingTypeMapper.java:71)
        at jnr.ffi.mapper.CachingTypeMapper.getToNativeType(CachingTypeMapper.java:43)
        at jnr.ffi.mapper.CompositeTypeMapper.getToNativeType(CompositeTypeMapper.java:34)
        at jnr.ffi.provider.jffi.InvokerUtil.getParameterTypes(InvokerUtil.java:185)
        at jnr.ffi.provider.jffi.AsmLibraryLoader.generateInterfaceImpl(AsmLibraryLoader.java:125)
        at jnr.ffi.provider.jffi.AsmLibraryLoader.loadLibrary(AsmLibraryLoader.java:59)
        at jnr.ffi.provider.jffi.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:43)
        at jnr.ffi.LibraryLoader.load(LibraryLoader.java:265)
        at jnr.ffi.LibraryLoader.load(LibraryLoader.java:244)

我使用
指针有什么问题?

如果它是C调用Java,我认为不可能仅仅从一个C指针给Java一个实际的Java数组

首先,Java数组对象具有内置长度,但C指针值本身不包含上限。C通常使用诸如以零结尾的字符串或传递两个参数(ptr、len)之类的约定

其次,在使用之前必须填充Java数组(即,不惰性)。这意味着加载所有指向数组的指针,这可能会导致效率低下。这也需要使用已知的数组长度来完成

我建议在访问指向数组的指针时,自己在Java中进行指针运算。这需要了解特定于平台的内存布局(例如指针数组中一个指针元素的长度),但所有本机接口都是特定于平台的。

如前所述

首先,Java数组对象具有内置长度,但C指针值本身不包含上限。C通常使用诸如以零结尾的字符串或传递两个参数(ptr、len)之类的约定

其次,在使用之前必须填充Java数组(即,不惰性)。这意味着加载所有指向数组的指针,这可能会导致效率低下。这也需要使用已知的数组长度来完成

一旦
void const**
void**
参数等同于未知大小的数组,您就应该对这些参数使用
jnr.ffi.byref.PointerByReference
,如下所示:

public int call(Pointer a, PointerByReference b, PointerByReference c);
那么您的方法的用法应该是这样的:

Pointer a = new Pointer.wrap(Runtime.getSystemRuntime(), variable);
PointerByReference b = new PointerByReference();
PointerByReference c = new PointerByReference();
call(a, b, c);
Pointer bValue = b.getValue();

为了进一步管理数据,您应该确切地知道您正在处理的数据类型。

发现:无论出于何种原因,指针数组在某个时候受到支持,然后被注释掉。或者它们是一个想法,在实施之前会被注释掉?还是什么?不管怎样,目前正在废弃
[]
s,通过
get
方法通过指针参数访问指针元素。。。