2012-04-15 12 views
5

के लिए स्ट्रिंग टू पॉइंटर कनवर्ट करना मैं विंडोज़ में फ़ाइल के लिए प्रभावी अनुमतियों से पूछने के लिए जेएनए का उपयोग करने की कोशिश कर रहा हूं। आखिरकार, मैं GetEffectiveRightsFromAcl function का उपयोग करने की योजना बना रहा हूं, लेकिन ऐसा करने के लिए, मुझे एक जनसंख्या वाले TRUSTEE structure पर एक सूचक प्रदान करने की आवश्यकता है। जेएनए प्लेटफार्म (platform.jar) इस संरचना को परिभाषित नहीं करता है, इसलिए मैं इसे स्वयं परिभाषित करने की कोशिश कर रहा हूं।जेएनए

public static class TRUSTEE extends Structure { 
    public TRUSTEE() { 
     super(); 
    } 
    public TRUSTEE(Pointer p) { 
     super(p); 
     read(); 
    } 

    public Pointer pMultipleTrustee; 
    public int MultipleTrusteeOperation; 
    public int TrusteeForm; 
    public int TrusteeType; 
    public Pointer ptstrName; 
} 

मैं इस तरह की संरचना को भरने के लिए कोशिश कर रहा हूँ: यहाँ मैं अब तक राशि है

private TRUSTEE createTrusteeForCurrentUser() { 
    TRUSTEE result = new TRUSTEE(); 
    result.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME; 
    result.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER; 

    String strName = "CURRENT_USER"; 
    // How can I set result.ptstrName using strName? 
} 

This Google Groups thread संरचनाओं में String क्षेत्रों का उपयोग करते समय एक char * के लिए कहा जाता है की सिफारिश की। हालांकि, मुझे नहीं लगता कि यह मेरी स्थिति में उपयुक्त है, ptstrName फ़ील्ड को TrusteeForm के मान के आधार पर विभिन्न प्रकार की चीजों को इंगित करने की अनुमति है। तो, मुझे लगता है कि मुझे किसी भी तरह String से Pointer में बदलने की आवश्यकता है। मुझे जेएनए में NativeString कक्षा मिली, जो काम करेगा, सिवाय इसके कि यह पैकेज-प्राइवेट क्लास है।

जावा String को मूल स्वरूप में बदलने के लिए अनुशंसित तरीका क्या है और इसे Pointer प्राप्त करें? क्या मैं TRUSTEE संरचना के लिए सही डेटा प्रकार का उपयोग भी कर रहा हूं? मैं जेएनए के लिए कुछ नया हूँ, तो कृपया मुझे क्षमा करें अगर मुझे कुछ स्पष्ट याद आ रही है।

अद्यतन

मैं अपने समस्या का समाधान मिल गया है, लेकिन मैं अभी भी यह सुनना चाहते हैं, तो किसी को भी एक बेहतर समाधान है।

उत्तर

2

मैं पैकेज-निजी NativeString वर्ग के लिए स्रोत कोड को कॉपी करने और अपने प्रोजेक्ट में एक सार्वजनिक प्रति बनाकर समस्या हल हो। मुझे कन्स्ट्रक्टर में पैकेज-प्राइवेट विधि के उपयोग के कारण एक मामूली बदलाव करना पड़ा।

अपडेट: टिप्पणियों में @fragorl नोट्स के रूप में, नीचे दिखाए गए मूल स्ट्रिंग का कार्यान्वयन अब काफी पुराना है।


उपयोग:

private static TRUSTEE createTrusteeForCurrentUser() { 
    TRUSTEE result = new TRUSTEE(); 
    result.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME; 
    result.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER; 
    result.ptstrName = new NativeString("CURRENT_USER",true).getPointer(); 
    result.write(); 
    return result; 
} 

NativeString.java:

/** Provides a temporary allocation of an immutable C string 
* (<code>const char*</code> or <code>const wchar_t*</code>) for use when 
* converting a Java String into a native memory function argument. 
* 
* @author Todd Fast, [email protected] 
* @author [email protected] 
*/ 
public class NativeString implements CharSequence, Comparable { 

    private Pointer pointer; 
    private boolean wide; 

    /** Create a native string (NUL-terminated array of <code>char</code>).<p> 
    * If the system property <code>jna.encoding</code> is set, its value will 
    * be used to encode the native string. If not set or if the encoding 
    * is unavailable, the default platform encoding will be used. 
    */ 
    public NativeString(String string) { 
     this(string, false); 
    } 

    /** Create a native string as a NUL-terminated array of <code>wchar_t</code> 
    * (if <code>wide</code> is true) or <code>char</code>.<p> 
    * If the system property <code>jna.encoding</code> is set, its value will 
    * be used to encode the native <code>char</code>string. 
    * If not set or if the encoding is unavailable, the default platform 
    * encoding will be used. 
    * 
    * @param string value to write to native memory 
    * @param wide whether to store the String as <code>wchar_t</code> 
    */ 
    public NativeString(String string, boolean wide) { 
     if (string == null) { 
      throw new NullPointerException("String must not be null"); 
     } 
     // Allocate the memory to hold the string. Note, we have to 
     // make this 1 element longer in order to accommodate the terminating 
     // NUL (which is generated in Pointer.setString()). 
     this.wide = wide; 
     if (wide) { 
      int len = (string.length() + 1) * Native.WCHAR_SIZE; 
      pointer = new Memory(len); 
      pointer.setString(0, string, true); 
     } 
     else { 
      byte[] data = Native.toByteArray(string); 
      pointer = new Memory(data.length + 1); 
      pointer.write(0, data, 0, data.length); 
      pointer.setByte(data.length, (byte)0); 
     } 
    } 

    public int hashCode() { 
     return toString().hashCode(); 
    } 

    public boolean equals(Object other) { 

     if (other instanceof CharSequence) { 
      return compareTo(other) == 0; 
     } 
     return false; 
    } 

    public String toString() { 
     String s = wide ? "const wchar_t*" : "const char*"; 
     s += "(" + pointer.getString(0, wide) + ")"; 
     return s; 
    } 

    public Pointer getPointer() { 
     return pointer; 
    } 

    public char charAt(int index) { 
     return toString().charAt(index); 
    } 

    public int length() { 
     return toString().length(); 
    } 

    public CharSequence subSequence(int start, int end) { 
     return CharBuffer.wrap(toString()).subSequence(start, end); 
    } 

    public int compareTo(Object other) { 

     if (other == null) 
      return 1; 

     return toString().compareTo(other.toString()); 
    } 
} 
+0

धन्यवाद, ऐसा करने के लिए यह "सही" तरीका प्रतीत होता है। एक प्रश्न - आपने 2-तर्क के बजाय 1-तर्क नेटिव स्ट्रिंग कन्स्ट्रक्टर का उपयोग क्यों नहीं किया? – fragorl

+0

@fragorl मेरे आवेदन के लिए मैं विस्तृत-वर्ण (यूनिकोड) स्ट्रिंग का उपयोग कर रहा था, इसलिए मुझे 'wide' पैरामीटर को 'true' पर सेट करने की आवश्यकता थी। 1-तर्क निर्माता इसे 'झूठी' पर सेट करता है। –

+0

आह मेरे बुरे, मैं जेना के नवीनतम संस्करण को देख रहा था, जहां उन्होंने 1-Arg कन्स्ट्रक्टर बदल दिया। अब यह पढ़ता है: यह (स्ट्रिंग, मूल .getDefaultStringEncoding()); लेकिन आपके पास पुराने संस्करण के लिए स्रोत कोड है - बेशक, आपकी पोस्ट 2012 से है, woops>< – fragorl

0

http://jna.java.net/javadoc/com/sun/jna/Pointer.html में पॉइंटर क्लास का उपयोग करने का प्रयास करें।

+0

मुझे लगता है मैं एक 'Pointer' जरूरत है पता है, मुझे लगता है कि प्रश्न अधिक कैसे एक देशी प्रारूप में एक जावा' स्ट्रिंग' बदलने और एक 'Pointer' प्राप्त करने के लिए है इसके लिए वस्तु। –

9

मान लिया जाये कि आप देशी तरफ char * चाहते हैं (आप और अधिक स्मृति आवंटित की आवश्यकता हो सकती है, तो स्ट्रिंग गैर ASCII वर्ण हैं),

String myString = "CURRENT_USER"; 
Pointer m = new Memory(myString.length() + 1); // WARNING: assumes ascii-only string 
m.setString(0, myString); 

तब आप m का उपयोग कर सकते हैं जहां भी आपको "मूल" स्ट्रिंग का संदर्भ देना होगा।

विस्तृत तार (wchar_t *) के लिए,

String myString = "CURRENT_USER"; 
Pointer m = new Memory(Native.WCHAR_SIZE * (myString.length() + 1)); 
m.setWideString(0, myString); 
+0

सेटस्ट्रिंग (ऑफसेट, मान) सेटस्ट्रिंग (ऑफसेट, मान, मूलभूत .getDefaultStringEncoding()) कॉल करता है। ऐसा लगता है कि मूल .getDefaultStringEncoding() हमेशा एक प्रारूप लौटाता है जो प्रति चरित्र केवल 1 बाइट का उपयोग करता है, जो आप आवंटित करते हैं? – fragorl

+0

आप सही हैं, उचित रूप से अद्यतन उत्तर दें। – technomage

+0

सूचक मीटर = नया मेमोरी (Native.WCHAR_SIZE * (myString.length() +1); , एक ब्रैकेट याद आ रही है इस सूचक मीटर = नया मेमोरी (Native.WCHAR_SIZE * (myString.length मतलब है () + 1)); ? – fragorl

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