2010-11-12 152 views
7

我有一个C++中的方法,它将一个双精度数组作为参数。我从Java调用这个方法,需要传递一个双精度数组。 C++例程读取和修改数组的值,我需要Java中的更新值。我该怎么做呢?如何使用Swig将数组从Java传递到C++?

例如,以C++程序:

void myMethod(double *values, int size) { 
    for (int i=0; i < size; i++) { 
     values[i] = 2*values[i]; 
    } 
} 

和Java代码:

double[] values = { 1.3, 1.1 }; 
myMethod(values,values.length); 
System.out.println(values[0]); // prints 2.6 

我猜myMethod的通话不能像上面的电话进行... ...还是可以? Swig有必要完成这项工作。如果我无法拨打上面的电话,那我该如何将我的值传给C++代码?

+1

SWIG由我的答案解决。其余的答案讨论替代方案。 – 2010-11-13 15:58:36

+0

是的,非常感谢你安迪!你理解我的问题并给出一个非常合适的答案......我仍然在寻找更多答案。我对大多数人所做的事情特别感兴趣,因为这种情况一定会出现。大多数人使用Swig 2吗?大多数人是否会编写自己的类型图?这两个听起来对我来说都是极端的。 – Jason 2010-11-14 16:24:28

+0

如果我必须手动将数组复制到C++中,那很好。如果我可以在C++中分配一个数组,并且必须使用特殊的方法来访问Java中的值,那很好。大多数人在这样的情况下做什么? – Jason 2010-11-14 16:31:59

回答

6

使用carrays.i!

Swig docs on carrays

%include carrays.i 
%array_functions(double, double_array) 

这两行创建我的模块下面的代码:

public static SWIGTYPE_p_double new_double_array(int nelements) { 
    long cPtr = SimulatorModuleJNI.new_double_array(nelements); 
    return (cPtr == 0) ? null : new SWIGTYPE_p_double(cPtr, false); 
    } 

    public static void delete_double_array(SWIGTYPE_p_double ary) { 
    SimulatorModuleJNI.delete_double_array(SWIGTYPE_p_double.getCPtr(ary)); 
    } 

    public static double double_array_getitem(SWIGTYPE_p_double ary, int index) { 
    return SimulatorModuleJNI.double_array_getitem(SWIGTYPE_p_double.getCPtr(ary), index); 
    } 

    public static void double_array_setitem(SWIGTYPE_p_double ary, int index, double value) { 
    SimulatorModuleJNI.double_array_setitem(SWIGTYPE_p_double.getCPtr(ary), index, value); 
    } 

,让我可以在Java C数组......这解决了我的需求,是我的问题的最佳解决方案。感谢大家的答案!

+0

感谢您发布更简单的方法。我认为你应该接受你自己的答案。有关Carrays的SWIG 2.0链接位于http://www.swig.org/Doc2.0/SWIGDocumentation.html#Library_carrays。 – 2010-11-14 17:03:00

+0

这是最快的方法吗?我假设您需要使用Java数组中的元素数来调用SWIGTYPE_p_double,然后将每个项目复制到新数组,然后在C++上对新数组执行处理,然后将每个项目复制回Java数组中。有没有办法做直接内存访问,只是在两种语言之间传递指针?还是这些额外的复制操作是唯一的方法来做到这一点,因为Java和Cxx之间的内存管理有所不同? – LaserJesus 2017-08-28 08:27:56

0

如果它只是单一的方法,它改写。如果你有一个(很多)C++代码库需要移植,请使用JNI(或者更简单的JNA)。这增加了很多代码开销,但它是可行的。

+0

嗯......这正是我正在做的......使用JNI,因为它是一个庞大的代码库。所以我选择使用Swig创建JNI包装器......因为Swig更简单。 – Jason 2010-11-14 16:18:23

1

SWIG typemaps应该允许这个。 SWIG 2.0文档显示example in Python

使用Java,您可以在SWIG类型映射中使用JNI代码。 JNI提供了Get/ReleaseArrayElements方法。我猜你可以在typemap(in)中得到一个本地数组,然后在typemap(argout)中释放它。

另一种方法是将数组复制到std :: vector中,使用std_vector.i中的现有SWIG类型映射。

+0

这是一个很好的答案!谢谢!我可以使用这个解决方案。但第一部分(编写我自己的类型映射)很复杂,第二部分需要Swig 2.此刻,我相信必须有一个更简单的解决方案......我不介意编写一些代码将数组复制到C中。我要更新我的问题......查看顶部的更新。 – Jason 2010-11-14 16:22:32

相关问题