2012-06-08 7 views
5

का उपयोग कर मैं नीचे की तरह नमूना ज फ़ाइल है:कैसे सरणी पारित करने के लिए (जावा में लंबे की सरणी) जावा से सेल्सियस तक ++ बड़ा घूँट

class Test 
{ 
public: 
     void SelectValues(long long values[]) 
}; 

मैं बड़ा घूँट का इस्तेमाल किया और मैं फ़ाइल

नीचे से JNI इंटरफ़ेस बनाया
%module MyLib 
%include "carrays.i" 
%array_functions(long long, long_long_array) 


%{ 
    #include "Test.h" 
%} 

/* Let's just grab the original header file here */ 
%include <windows.i> /*This line is used for calling conventions*/ 
% include "Test.h" 

जब मैं जावा विधि बनाने यह बनाता है की तरह:

public void SelectValues(SWIGTYPE_p_long_long includeKeys) 

इसके अलावा JNI फ़ाइल के लिए यहके रूप में तर्क ले जा रहा हैलेकिन केवल सरल jlong ले रहा है। इस मुद्दे के कारण मैं लंबे समय तक long[]={1L,2L} की सरणी नहीं बना सकता और उपयुक्त जेएनआई विधि को कॉल करने के लिए इसे जावा विधि से ऊपर भेज सकता हूं।

मैं चाहता हूं कि एसडब्ल्यूआईजी इस तरह से इंटरफेस उत्पन्न करे कि मैं अपने सी ++ विधि में ऊपर उल्लिखित सरणी पास कर सकता हूं।

मैंने this question पढ़ा है, लेकिन यह मुझे जावा से सी ++ में सरणी को पास करने का तरीका देखने में मदद नहीं करता है।

+0

जेएनआई पक्ष पर आपने देखा 'जंगल' यह है कि कैसे SWIG सब कुछ लपेटता है जो एक प्राचीन प्रकार नहीं है। – Flexo

उत्तर

2

आपने array_functions के साथ यहां क्या किया है, यह सही और प्रयोग योग्य है, लेकिन यह सी ++ कोड को सीधे लपेटने पर केंद्रित है, और यह अंतर्निहित जावा सरणी का उपयोग नहीं करेगा। आप की तरह कुछ के साथ उपयोग कर सकते हैं:

SWIGTYPE_p_long_long array = MyLib.new_long_long_array(100); // new array with 100 elements. 
for (int i = 0; i < 100; ++i) { 
    long_long_array_setitem(array, i, i); 
} 
new Test().SelectValues(array); 

जहां सरणी एक 'असली' सी ++ स्मृति की है कि आप जावा तरफ से पढ़ने/लिखने और लिपटे कार्यों के लिए पारित कर सकते हैं हिस्सा करने के लिए सिर्फ एक प्रॉक्सी है।

मैं आपके प्रश्न से अनुमान लगा रहा हूं कि आप इसे जावा पक्ष पर अधिक "प्राकृतिक" महसूस करने में रुचि रखते हैं। एसडब्ल्यूआईजी array_class भी प्रदान करता है जो समान रूप से एक सरणी को लपेटता है, लेकिन स्थैतिक कार्यों के संग्रह के बजाय उचित वस्तु के रूप में। उदाहरण के लिए यदि आप अपने इंटरफेस फ़ाइल array_functions के बजाय array_class(long long, LongLongArray) उपयोग करने के लिए बदल गया है आप कर सकते हैं:

LongLongArray array = new LongLongArray(100); 
for (int i = 0; i < 100; ++i) { 
    array.setitem(i,i); 
} 
new Test().SelectValues(array.cast()); 

आप वास्तव में बड़ा घूँट में कुछ typemaps साथ तुलना में अधिक कर आप करना चाहते हैं तो कर सकते हैं। आपकी उदाहरण कक्षा में SelectValues में कोई लंबाई नहीं लगती है, इसलिए मुझे लगता है कि आप सरणी को समाप्त कर रहे हैं, हालांकि आप कुछ सरल परिवर्तनों के साथ लंबाई को समान रूप से अच्छी तरह से पास कर सकते हैं।

(सुविधा के लिए मैं %inline अपनी कक्षा d फ़ाइलों की संख्या कम करने के लिए और परीक्षण के लिए इसके बारे में एक डमी कार्यान्वयन जोड़ा)

%module MyLib 

%{ 
#include <iostream> 
%} 

%typemap(jtype) long long values[] "long[]" 
%typemap(jstype) long long values[] "long[]" 
%typemap(javain) long long values[] "$javainput" 
%typemap(jni) long long values[] "jlongArray" 
%typemap(in) long long values[] { 
    jboolean isCopy; 
    $1 = JCALL2(GetLongArrayElements, jenv, $input, &isCopy); 
} 

%inline %{ 
class Test 
{ 
public: 
    void SelectValues(long long values[]) { 
    while (*values) { 
     std::cout << *values++ << "\n"; 
    } 
    } 
}; 
%} 

यहाँ हम ने कहा कि दोनों प्रॉक्सी वर्ग बड़ा घूँट उत्पन्न करता है और JNI यह वर्ग उत्पन्न long[], यानी एक जावा सरणी के साथ काम करने जा रहे हैं। जावा जावा में जावा जेएनआई रूपांतरण में हमें कुछ भी करने की ज़रूरत नहीं है, इसलिए javain टाइपमैप सिर्फ एक सीधा पास है। जेएनआई के सी ++ पक्ष पर jlongArray है, जिसे हमने अन्य टाइपमैप में भी निर्दिष्ट किया है।

हम तो एक in typemap जरूरत सी ++ पक्ष में long long[] को jlongArray से परिवर्तित व्यवस्था करने के लिए - यह है कि के लिए एक एकल JNI कॉल और हम परवाह नहीं है अगर यह एक प्रति या JVM है कि हम अंत से वास्तविक स्मृति है का उपयोग करते हुए।(यदि आप परिणाम को संशोधित करने और यह दिखाई वापस जावा अंदर उदाहरण के लिए बनाना चाहते थे परवाह सकता है)

मैं के साथ इस परीक्षण किया:

public class run { 
    public static void main(String[] argv) { 
    System.loadLibrary("mylib"); 
    long arr[] = {100,99,1,0}; // Terminate with 0! 
    new Test().SelectValues(arr); 
    } 
} 

कौन वास्तव में किया था के रूप में आप आशा होगी।

+0

यदि आप सरणी को समाप्त करने के लिए 0 का उपयोग नहीं करना चाहते हैं तो आपको SelectValues ​​को कुछ ऐसा करने की आवश्यकता होगी: 'शून्य चयन वैल्यूज (लंबे समय तक मान [], size_t len);' - मैं इसे अपने उत्तर में जोड़ सकता हूं यदि आप चाहते हैं। – Flexo

+0

मैंने अंत में उस उदाहरण को जोड़ा: http://stackoverflow.com/q/11584599/168175 – Flexo

संबंधित मुद्दे