2010-11-27 11 views
7

मैं जेएनए से सी में इस विधि हस्ताक्षर के साथ एक विधि कैसे कॉल कर सकता हूं?जावा में नया पॉइंटर कैसे प्राप्त करें?

int open_device(context *ctx, device **dev, int index); 

सी विधि के अंतिम दो पंक्तियों इस तरह दिखेगा:

*dev = pdev; 
return 0; 

कि विधि में dev का ही फायदा नहीं है यही कारण है कि। इसका मतलब है कि मुझे विधि में एक खाली सूचक को एक पॉइंटर पास करना होगा, है ना? विधि तब device ऑब्जेक्ट के पते के साथ खाली सूचक को भरती है और मैं डिवाइस को अन्य तरीकों से पॉइंटर पास कर सकता हूं।

मेरा सवाल है: क्या ऐसा करने का यह सही तरीका है? यदि ऐसा है, तो मैं जावा से एक नया सूचक कैसे आवंटित करूं?


स्वीकार किए जाते हैं जवाब के आधार पर मैंने ऐसा किया:

Memory p = new Memory(Pointer.SIZE); 
Memory p2 = new Memory(Pointer.SIZE); 
p.setPointer(0, p2); 
nativeLib.open_device(ctx, p, index); 
return p2; 
+0

बस उत्सुक: क्या आपके अपडेट किए गए कोड आपके लिए काम करते हैं? ऐसा लगता है कि आप '* p = p2' सेट कर रहे हैं लेकिन फिर सी फ़ंक्शन' * p = pdev' करेगा जिससे इस प्रकार मूल्य को ओवरराइट किया जा सके। – casablanca

+0

@ कैसाब्लांका: हाँ, मैंने इसका परीक्षण किया, यह काम करता है। – thejh

+0

@thejh क्या आप जानते हैं कि अमान्य स्मृति पते को इंगित करने के कारण अवैध MemoryAccess अपवाद को कैसे प्रबंधित किया जाए? – mayooran

उत्तर

9

ऐसा लगता है कि JNA Pointer वर्ग setPointer और getPointer तरीकों है एकाधिक अविवेक के लिए अनुमति देने के लिए, और Memory वर्ग वास्तव में "आवंटित" के मूल निवासी वस्तुओं। तो अगर आप की तरह कुछ करने के लिए सक्षम होना चाहिए: (मैं सिर्फ JNA डॉक्स से अनुमान लगा रहा हूँ, मैं इस परीक्षण नहीं किया गया है)

Pointer pDev = new Memory(Pointer.SIZE); // allocate space to hold a pointer value 
// pass pDev to open_device 
Pointer dev = pDev.getPointer(0);  // retrieve pointer stored at pDev 
+0

आह, वह 'नई मेमोरी (पॉइंटर.एसआईजेई);' ऐसा लगता है कि मुझे इसकी ज़रूरत है, धन्यवाद। – thejh

0

जावा में कोई संकेत, केवल संदर्भ हैं।

जब आप उन्हें विधियों पर पास करते हैं तो आप किसी संदर्भ को पुन: असाइन नहीं कर सकते हैं, क्योंकि आप उन्हें मूल्य से पास करते हैं। जावा में मूल्य से सब कुछ पारित किया जाता है।

आप डिवाइस के एक नए इंस्टेंस को तुरंत चालू करने के लिए इस विधि को फिर से लिख सकते हैं और एक int के बजाय इसे वापस कर सकते हैं।

+3

@ डफिमो: मैं जेएनए पॉइंटर्स के बारे में बात कर रहा था: https://jna.dev.java.net/javadoc/com/sun/jna/Pointer.html – thejh

+0

जेएनए के बिना ऐसा करना संभव है। आपको केवल उस डिवाइस ऑब्जेक्ट का नया संदर्भ वापस करना होगा जिसे आप int के बजाय तत्काल करते हैं। – duffymo

+2

@duffymo: और मैं इस स्पष्ट रूप से देशी सामान के बिना जावा का उपयोग कर सी पुस्तकालय (libbla.so) तक कैसे पहुंच सकता हूं? – thejh

0

और भी बेहतर जवाब। आप जावा स्ट्रिंग लंबाई के आधार पर आवंटित करना चाहते हैं (malloc आदि)। नीचे उदाहरण जेएनए परियोजना से यूनिट परीक्षण है।

public void testGetSetStringWithDefaultEncoding() throws Exception { 
    final String ENCODING = Native.DEFAULT_ENCODING; 
    String VALUE = getName(); 
    int size = VALUE.getBytes(ENCODING).length+1; 
    Memory m = new Memory(size); 
    m.setString(0, VALUE); 
    assertEquals("Wrong decoded value", VALUE, m.getString(0)); 
} 
संबंधित मुद्दे