我遇到的问题是从我的Java实现(下面两者)中为fetchByType C函数的length参数传递适当的Java数据类型。在C端,* length参数是指向长度变量(输出)的指针,以指示要从fetchByType C函数返回的数据的大小。我试图使用SWIG%apply int32_t {int32_t *}并从我的Java实现传递一个初始化为0的int,但是失败了。我也试过传递一个SWIGTYPE_p_int,如下所示,但这也行不通。不幸的是,我没有例外,因为这只是崩溃。
C函数:
void * fetchByType(struct row_t *result_row, type_t attribute, int32_t *length);
SWIG生成的Java:
public static String fetchByType(SWIGTYPE_p_result_row_t result_row, type_t attribute, SWIGTYPE_p_int length)
Java实施:
SWIGTYPE_p_int length = new SWIGTYPE_p_int();
fetchByType(result_row, attribute, length)
答案 0 :(得分:3)
这里的问题是您需要将可以更改的内容传递给C函数。这意味着你不能在Java中使用原语(例如int
),因为Java 总是按值传递原语。
只有一种明智的方法可以解决这个问题。事实上,SWIG已经提供了一些我们可以使用的类型映射,它将此作为数组传递。 Java中的数组是“对象”,因此即使int[]
不是int
,也会通过引用传递inline void fetchByType(int32_t *length) {
*length = 123;
}
。基于上面显示的函数的简化示例,首先是test.h:
%module test
%{
#include "test.h"
%}
// knows about things like int *OUTPUT:
%include "typemaps.i"
// knows about int32_t
%include "stdint.i"
// let's have an int32_t *OUTPUT for our int32_t *lenght
%apply int32_t *OUTPUT { int32_t *length }
%include "test.h"
一个模块文件,test.i:
*OUTPUT
这只是确保我们应用适当的public class run {
public static void main(String[] argv) {
int arr[] = new int[1];
test.fetchByType(arr);
System.out.println(arr[0]);
}
}
typemap。 (stdint.i将此映射到真实的C原语上)。我测试了:
int
这是一个hack 1 ,但它可以使用。另一种方法可能是使用java.lang.Integer
,它也代表Object
并且是正确的java.lange.Integer
,因此通过引用传递。问题是{{1}} is immutable然而我并不确定JNI方面的工作方式如何提供一个例子。
1 其他语言SWIG支持更改某些类型映射的返回类型,并返回OUTPUT参数的元组或类似内容,但这对Java来说并不可行。