You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Swig在C与Java间传递数组遇类型不兼容问题求助

我来帮你搞定这个SWIG调用C数组的问题——你碰到的那个incompatible types错误,核心问题出在你的.i文件没有正确配置SWIG的类型映射,导致SWIG把C的double*默认生成了SWIGTYPE_p_double封装类,而不是直接和Java的double[]做关联。


问题根源

SWIG不会自动把C的指针类型(比如double*)映射到Java的原生数组类型(double[]),它默认会生成一个SWIGTYPE_p_*的封装类来表示C指针。你之前尝试了carrays.i和arrays_java.i但配置不到位,所以类型不匹配的错误依然存在。

解决方案:修正你的AMItest.i文件

我们用arrays_java.i来告诉SWIG将C的double*参数直接映射为Java的double[],并且因为你的C函数会修改数组内容(属于输入输出双向参数),所以要使用INOUT类型映射来处理数据的双向传递。

修改后的AMItest.i内容如下:

%module AMItest
%{
// SWIG需要包含的C头文件内容
#include "AMItest.h"
%}

// 引入arrays_java.i,它提供了Java数组与C指针的映射支持
%include "arrays_java.i"

// 关键配置:将C函数中的double* Array参数映射为Java的double[](输入输出双向)
%apply double INOUT[] { double *Array };

// 引入C头文件,让SWIG处理函数声明
%include "AMItest.h"

为什么之前的尝试没生效?

你之前添加的%apply (double *OUTPUT, int, int) {(double *Array, int Start, int End)};格式不正确——SWIG的%apply是针对单个参数的类型映射,而非整个参数列表。另外,你的数组既是输入(C函数需要读取数组内存空间)也是输出(C函数会修改数组内容),所以应该用INOUT而非单纯的OUTPUT。

编译运行验证

保持你原来的编译步骤不变:

$ rm -f AMItest AMItest*.java SWIG*.java *.class *.o *.a *.so *_wrap.c
$ swig -java AMItest.i
$ gcc -fPIC -c AMItest.c AMItest_wrap.c -I/usr/lib/jvm/java-11-openjdk-amd64/include -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux
$ gcc -shared AMItest.o AMItest_wrap.o -W -o libAMItest_swig.so
$ javac main.java

现在运行java main,你会看到C函数修改后的数组内容被正确打印,之前的类型错误也会消失。

补充:carrays.i的替代方案

如果你更倾向于用carrays.i,需要手动在Java代码中创建SWIG管理的数组对象,再转换为原生数组,步骤如下:

  1. 修改AMItest.i:
%module AMItest
%{
#include "AMItest.h"
%}
%include "carrays.i"
// 生成double数组的操作函数
%array_functions(double, doubleArray)
%include "AMItest.h"
  1. 修改main.java:
public class main {
 public static void main(String argv[]) {
 System.loadLibrary("AMItest_swig");
 // 创建SWIG管理的double数组
 SWIGTYPE_p_double myArray = AMItest.new_doubleArray(11);
 // 调用C函数
 System.out.println(AMItest.AMItest(myArray, 10, 20));
 // 将SWIG数组转换为Java原生数组
 double[] javaArray = new double[11];
 for (int i=0; i<11; i++) {
    javaArray[i] = AMItest.doubleArray_getitem(myArray, i);
 }
 // 打印结果
 for (int i=0; i<javaArray.length; i++) System.out.print(javaArray[i] + " ");
 // 释放SWIG数组内存
 AMItest.delete_doubleArray(myArray);
 }
}

不过显然arrays_java.i的方案更简洁,直接使用Java原生数组,不需要手动管理SWIG数组的内存。


内容的提问来源于stack exchange,提问作者dargaud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:52:26