配置 SWIG 以使用 int32_t 输出参数为 C 函数创建适当的 Java 数据类型
我在从 Java 实现(均在下面)中为 fetchByType C 函数的长度参数传递适当的 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)
I'm having issues passing in an appropriate Java data type for the fetchByType C function's length parameter from my Java implementation (both below). On the C side, the *length parameter is a pointer to a length variable (output) to indicate the size of the data to be returned from the fetchByType C function. I've tried to use the SWIG %apply int32_t { int32_t * } and pass an int initialized at 0 from my Java implementation but that fails. I've also tried passing in a SWIGTYPE_p_int as shown below, but that also doesn't work. I don't have an exception unfortunately as this just crashes.
C Function:
void * fetchByType(struct row_t *result_row, type_t attribute, int32_t *length);
Generated Java from SWIG:
public static String fetchByType(SWIGTYPE_p_result_row_t result_row, type_t attribute, SWIGTYPE_p_int length)
Java Implementation:
SWIGTYPE_p_int length = new SWIGTYPE_p_int();
fetchByType(result_row, attribute, length)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的问题是你需要传递一些可以改变的东西到C函数中。这意味着您不能在 Java 中使用原语(例如
int
),因为 Java 总是按值传递原语。只有一种明智的方法可以解决这个问题。 SWIG 实际上已经提供了一些我们可以使用的类型映射,将其作为数组传递。 Java 中的数组是“对象”,因此
int[]
是通过引用传递的,尽管int
不是。一个基于上面显示的函数的简化示例,首先是 test.h:和一个模块文件 test.i:
这只是确保我们应用适当的
*OUTPUT
类型映射。 (stdint.i 为您将其映射到真正的 C 原语)。我测试过:这有点像黑客1,但它是可用的。另一种方法可能是使用
java.lang.Integer
,它也表示一个int
并且是一个正确的Object
,因此通过引用传递。那里的问题是java.lange.Integer
是不可变的我实际上不太确定 JNI 端是如何工作的,无法提供一个例子。1 其他语言 SWIG 支持更改某些类型映射的返回类型并返回元组或类似的 OUTPUT 参数,但这对于 Java 来说实际上并不可行。
The problem here is that you need to pass something that can be changed into the C function. That means you can't use a primitive in Java (e.g.
int
) since Java always passes primitives by value.There's only really one sensible way you can work around this. SWIG in fact already provides a few typemap we can use that passes this as an array instead. Arrays in Java are "objects" and so
int[]
is passed by reference even thoughint
isn't. A simplified example based on the function you show above, first test.h:And a module file, test.i:
This just makes sure we apply the appropriate
*OUTPUT
typemap. (stdint.i maps this onto a real C primitive for you). I tested with:It's a bit of a hack1, but it's usable. Another approach might be to use a
java.lang.Integer
, which also represents anint
and is a properObject
so gets passed by reference. The problem there is thatjava.lange.Integer
is immutable however and I'm not actually sure enough how that works on the JNI side to provide an example of this.1 Other languages SWIG supports alter the return type for some typemaps and return a tuple or similar for OUTPUT arguments, but that's not really feasible with Java.