2017-02-04 12 views
6

मैं जेएनए के साथ सी में एक छोटा ** कॉल करने का प्रयास करता हूं।जेएनए दो आयामी सरणी

सी इस तरह दिखता है:

void compute(short** in, int row, int col) { 
    for (int i = 0; i < row; i++) { 
     for (int j = 0; j < col; j++) { 
      printf("in[%d][%d] = %d\n", i,j, in[i][j]); 
     } 
    } 
} 
  • पासिंग एक छोटी [] [] JNA काम नहीं करता है से।

  • जेएनए दस्तावेज कहता है "मूल बहु-आयामी सरणी को मैप करने के लिए, एकल-आयामी जावा सरणी का उपयोग करें" लेकिन यह काम नहीं करता है।

    'nativeLib.compute (नया छोटा [] {1, 2, 3, 4}, 2, 2) कॉल करते समय; मैं: java.lang.Error: com.sun.jna.Native.invokeVoid (मूल निवासी विधि) पर अवैध मेमरी पहुँच

  • ऐसा लगता है कि एक PointerByReference की जरूरत है, मैं PointerByReference जिसमें साथ PointerByReference को भरने के लिए करने की कोशिश की कम मूल्यों, लेकिन यह काम नहीं करता है:

    Pointer pointerOfArray = new Memory(row * col * Native.getNativeSize(Short.TYPE)); 
    for(int i=0;i<row;i++) { 
    
        Pointer pointer = new Memory(col * Native.getNativeSize(Short.TYPE)); 
        for(int j=0;j<col;j++) { 
         pointer.setShort(j*Native.getNativeSize(Short.TYPE), in[i][j]); 
        } 
        pointerOfArray.setPointer(i*row*Native.getNativeSize(Short.TYPE), pointer); 
    } 
    
  • मैं भी करने की कोशिश की:

    Pointer pointer = new Memory(4*Short.SIZE); 
    
    Pointer pointer1 = new Memory(2*Short.SIZE); 
    pointer1.setShort(0,(short)1); 
    pointer1.setShort(Short.SIZE,(short)2); 
    
    Pointer pointer2 = new Memory(2*Short.SIZE); 
    pointer2.setShort(0,(short)3); 
    pointer2.setShort(Short.SIZE,(short)4); 
    
    pointer.setPointer(0, pointer1); 
    pointer.setPointer(2*Short.SIZE, pointer2); 
    
    nativeLib.compute(new PointerByReference(pointer), 2,2); 
    

लेकिन मैंमिल

क्या किसी के पास कोई विचार है? मैं सी हस्ताक्षर नहीं बदल सकता, मुझे इस लघु **

से बहुत कुछ सौदा करना है।

समाधान

मैं finnaly succed! ऐसा करने:

 short[][] in = { 
      {1,2,3}, 
      {4,5,6}, 
    }; 

    Pointer[] data = new Pointer[in.length]; 
    for(int i=0;i<in.length;i++) { 
     data[i] = new Memory(2*Short.SIZE); 
     data[i].write(0, in[i], 0,in[0].length); 
    } 

    nativeLib.compute(data, in.length,in[0].length); 
परिणाम के साथ

:

in[0][0] = 1 
in[0][1] = 2 
in[0][2] = 3 
in[1][0] = 4 
in[1][1] = 5 
in[1][2] = 6 

धन्यवाद एक बहुत!

+0

"पॉइंटर्स की सरणी" संस्करण आपके लिए काम करने के लिए खुशी हुई! –

उत्तर

2

जेएनए केवल एकल आयाम सरणी को संभालता है।

और तकनीकी रूप से, सी ए short * एक 1 डी, 2 डी, या 3 डी सरणी हो सकता है। आप तब तक नहीं जानेंगे जब तक आप आंतरिक नहीं जानते थे। केवल दस्तावेज़ीकरण पढ़कर आप जानते हैं कि फ़ंक्शन 2 डी सरणी की अपेक्षा कर रहा है। आप वास्तव में कर रहे हैं सरणी के पहले तत्व (कुल लंबाई पंक्ति * कर्नल) के लिए एक पॉइंटर पास कर रहा है, और फिर परिणाम लाने के लिए (rowIndex * col + colindex) का उपयोग करें। जेएनए में आप मैच के लिए केवल 1 डी सरणी का उपयोग करेंगे।

इस मामले में, हालांकि, आपके पास short ** है, इसलिए आप जानते हैं कि आपके पास 1 डी सरणी पॉइंटर्स हैं, प्रत्येक पॉइंटर short एस के 1 डी सरणी को इंगित करता है। जेएनए में, आप पहले * के लिए पॉइंटर्स (Pointer[]) की एक सरणी बनाते हैं; प्रत्येक एक नई पंक्ति (दूसरा *) के पहले "कॉलम" को इंगित करेगा।

Invalid Memory Access त्रुटि इंगित करता है कि आपने मूल स्मृति को सही ढंग से आवंटित नहीं किया है, और आपको उत्तर पर एक मजबूत संकेत देता है: आप केवल पैरामीटर के रूप में एक आदिम सरणी को पास नहीं कर सकते हैं। आपको Memory कक्षा का उपयोग करके या Structure के हिस्से के रूप में सरणी समेत अपनी याददाश्त आवंटित करनी होगी।

new short[] {1, 2, 3, 4} यहां काम नहीं करता है, क्योंकि आपने उस सरणी के लिए जावा स्मृति का समर्थन करने के लिए देशी-पक्ष स्मृति आवंटित नहीं की है। Memory कक्षा का उपयोग कर आप उस स्मृति आवंटन के साथ सही रास्ते पर थे।

सी में, short** in पॉइंटर्स की एक श्रृंखला की उम्मीद कर रहा है। अब

p[0] = new Memory(col * Native.getNativeSize(Short.TYPE)); 
p[1] = new Memory(col * Native.getNativeSize(Short.TYPE)); 

, आप अपने सरणी मान लिख सकते हैं: तो आप संकेत की एक सरणी की घोषणा के द्वारा बाहर शुरू कर देना चाहिए:

Pointer[] p = new Pointer[row]; 

तो फिर तुम, प्रत्येक पंक्ति के लिए संकेत सेट करेंगे स्मृति आवंटित किए जाएं। आप और स्तंभों पर पुनरावृति सकता है ऑफसेट के साथ setShort() लेकिन आप यह भी सीधे Pointer.write() उदा का उपयोग कर लिख सकते हैं,

p[0].write(0, new short[] {1, 2}, 0, 2); 
p[1].write(0, new short[] {3, 4}, 0, 2); 

तो फिर तुम in के लिए देशी सेल्सियस तक p से होकर गुजरेगा।

+0

पहले समाधान के बारे में, 'originalLib.compute (नया छोटा [] {1, 2, 3, 4}, 2, 2) पर कॉल करें;' एक देता है; "थ्रेड में अपवाद" मुख्य "java.lang.Error: अमान्य मेमोरी एक्सेस \t com.sun.jna.Native.invokeVoid (मूल विधि)" –

+0

मैंने अपना जवाब अपडेट कर दिया है ... –

+0

आपकी मदद के लिए बहुत बहुत धन्यवाद यह ठीक है, लेकिन दोनों अद्यतन समाधानों के साथ परिणाम है: '[0] [0] = 1 [0] [1] = 2 [1] [0] = 3200 [1] [1] में ] = 10525' –

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