配置SWIG以使用int32_t输出参数为C函数创建适当的Java数据类型

时间:2011-11-30 20:21:46

标签: java swig

我遇到的问题是从我的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)

1 个答案:

答案 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来说并不可行。