2011-09-16 14 views
5

साथ जावा के लिए सी से एक सरणी लौटने मैं इस तरह एक सी समारोह है:बड़ा घूँट

void get_data(const obj_t *obj, short const **data, int *data_len); 

मैं इसे बड़ा घूँट के लिए विशेष रूप से इस तरह लिखा था, के बाद से

const short *get_data(const obj_t *obj, int *data_len); 

कारणों मुसीबत, बड़ा घूँट के typemaps के रूप में वापसी मूल्य के साथ data_len को जोड़ने के लिए पर्याप्त स्मार्ट नहीं हैं।

जावा में मैं इस तरह इस समारोह कॉल करने के लिए सक्षम होना चाहते हैं:

short data[]= mylib.get_data(obj); 

लेकिन मैं समझ नहीं कैसे सरणी उत्पादन पैरामीटर एक वापसी मान बनने के लिए मिलता है। रुबी और पायथन के साथ यह ठीक काम करता है, क्योंकि उन भाषाओं के लिए एसडब्ल्यूआईजी आउटपुट पैरा को रिटर्न वैल्यू के रूप में लौटने का समर्थन करता है (क्योंकि भाषाओं में कई रिटर्न वैल्यू हो सकते हैं)।

मैं जावा के साथ काम करने के लिए इसे कैसे प्राप्त कर सकता हूं?

+0

आप अभी भी इस के लिए एक समाधान के लिए देख रहे हैं? – Flexo

+0

हाँ मुझे अभी भी यह नहीं पता कि यह कैसे करें – paleozogt

+0

मैंने उत्तर दिया है कि आपके द्वारा पूछे गए जावा सिंटैक्स से बिल्कुल मेल खाता है। मूल सी फ़ंक्शन के साथ उत्तर देने का एक संभावित तरीका है, हालांकि, यदि आप सरणी भरने के बिना आकार पूछ सकते हैं। यदि आप रुचि रखते हैं तो मैं इसे अपने उत्तर में जोड़ दूंगा। – Flexo

उत्तर

7

मैं एक साथ रख दिया निम्नलिखित परीक्षण हेडर फाइल समस्या प्रदर्शित करने के लिए:

%module test 

%{ 
#include "test.h" 
%} 

तब:

typedef struct { } obj_t; 

const short *get_data(const obj_t *obj, int *data_len) { 
    (void)obj; 
    static short arr[] = {1,2,3,4,5}; 
    *data_len = sizeof(arr)/sizeof(*arr); 
    return arr; 
} 

मैं मॉड्यूल फ़ाइल मैंने लिखा के माध्यम से बात करेंगे, यह बहुत मानक शुरू होता है हमने data_len तर्क के लिए एक टाइपमैप सेट अप किया है। इसे जावा पक्ष पर दिखाई देने की आवश्यकता नहीं है क्योंकि लंबाई सरणी द्वारा जानी जाएगी, लेकिन हमें पॉइंटर के लिए कुछ भंडारण की व्यवस्था करने की आवश्यकता है और हम सुनिश्चित करते हैं कि यह काफी देर तक चलता है कि हम इसे बाद में पढ़ सकते हैं जावा में सरणी लौटने पर भी।

%typemap(in,numinputs=0,noblock=1) int *data_len { 
    int temp_len; 
    $1 = &temp_len; 
} 

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

%typemap(jstype) const short *get_data "short[]" 
%typemap(jtype) const short *get_data "short[]" 

और JNI पक्ष में jshortArray - वहाँ एक प्रॉक्सी प्रकार का निर्माण करने की कोई जरूरत नहीं है, तो हम सिर्फ पारित दिए गए मान सीधे के माध्यम से:

%typemap(jni) const short *get_data "jshortArray" 
%typemap(javaout) const short *get_data { 
    return $jnicall; 
} 

अंत में हम एक typemap कि एक नई सरणी बनाने के लिए जा रहा है, आकार के साथ लंबाई मज़ा से लौटे के आधार पर बनाए उद्धरण और हमारे लिए जावा सरणी में लौटा परिणाम कॉपी करें। यदि आवश्यक हो तो हमें free() वास्तविक परिणाम सरणी चाहिए, लेकिन मेरे उदाहरण में इसे स्थाई रूप से आवंटित किया गया था इसलिए इसे मुक्त करने की आवश्यकता नहीं थी।

public class run { 
    public static void main(String argv[]) { 
    System.loadLibrary("test"); 
    obj_t obj = new obj_t(); 
    short[] result = test.get_data(obj); 
    for (int i = 0; i < result.length; ++i) { 
     System.out.println(result[i]); 
    } 
    } 
} 

कौन सा उत्पादित:

%include "test.h" 

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

%typemap(out) const short *get_data { 
    $result = JCALL1(NewShortArray, jenv, temp_len); 
    JCALL4(SetShortArrayRegion, jenv, $result, 0, temp_len, $1); 
    // If the result was malloc()'d free it here 
} 

अंत में हम typemaps हम सिर्फ लिखा था का उपयोग कर, के लिए बड़ा घूँट रैप करने के लिए हेडर फाइल शामिल

 
1 
2 
3 
4 
5 

संदर्भ के लिए आप लिपटे हो सकता था:

void get_data(const obj_t *obj, short const **data, int *data_len); 
भी

हालांकि आपके समारोह सरणी की स्थापना के बिना आकार क्वेरी करने के लिए जावा पर सही आकार की एक सरणी आवंटित करके आप इस थोड़ा होशियार लपेट कर सकता है एक तरह से था पक्ष। ऐसा करने के लिए आप जावा में एक इंटरमीडिएट फ़ंक्शन लिखना चाहते हैं जो आकार पूछता है, कॉल सेट करता है और फिर परिणामस्वरूप सरणी लौटाता है। इससे आपको संभावित 0 कॉपी कॉल के लिए GetShortArrayElements/ReleaseShortArrayElements का उपयोग करने की अनुमति मिल जाएगी।

इसका कारण यह है जावा में सरणियों मूल रूप से संदर्भ द्वारा पारित कर रहे हैं काम करेगा, उदा .:

public class ret { 
    public static void foo(int arr[]) { 
    arr[0] = -100; 
    } 

    public static void main(String argv[]) { 
    int arr[] = new int[10]; 
    System.out.println(arr[0]); 
    foo(arr); 
    System.out.println(arr[0]); 
    } 
} 
+2

सुविधा के लिए मैं अपनी साइट पर परीक्षण करने के लिए उपयोग की जाने वाली पूरी इंटरफ़ेस फ़ाइल: http://static.lislan.org.uk/~ajw/javaarrout.i - अगर उस लिंक को तोड़ना चाहिए तो जवाब कुछ भी खो देता है क्योंकि यह हो सकता है उत्तर से ही पुन: उत्पन्न हुआ। – Flexo

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