2010-11-12 33 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

相關問題