2009-08-12 10 views
5

से char * लेता है मैं पीओओबीजेसी के साथ एक निजी ढांचे का उपयोग करने की कोशिश कर रहा हूं। मुझे यह अब तक मिल गया है:एक चयनकर्ता को कॉल करें जो पीओओबीजेसी

from AppKit import * 
from Foundation import * 
import objc 

framework="/System/Library/PrivateFrameworks/DSObjCWrappers.framework" 
objc.loadBundle("DSObjCWrapper", globals(), framework) 

directory = DSoDirectory.alloc() 
directory.initWithHost_user_password_("server", "diradmin", "password") 

eDSStartsWith = 0x2002 
node = directory.findNode_matchType_(u"/LDAPv3", eDSStartsWith) 

यह ठीक काम करता है। अब, मैं इस उद्देश्य-सी हस्ताक्षर के साथ, मेरे नोड (कक्षा डीएसओएनओडी) पर एक विधि कॉल करना चाहता हूं।

  • (BOOL) hasRecordsOfType: (स्थिरांक चार *) inType

सबसे स्पष्ट रास्ता कैसे एक स्ट्रिंग लेने के लिए पता नहीं है और यह एक चार * के पास:

node.hasRecordsOfType_("dsRecTypeStandard:ComputerLists") 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 

/Users/clinton/<ipython console> in <module>() 

ValueError: depythonifying 'char', got 'str' of 31 

ऐसा लगता है कि हस्ताक्षर को बदलना संभव है क्योंकि पाइथन इसे देखता है। मैं इस पर कुछ रूपों की कोशिश की:

objc.registerMetaDataForSelector("DSoNode", "hasRecordsOfType_", dict(arguments={ 2+0: dict(type_modifier='n', type='^C') })) 

लेकिन - और स्पष्ट रूप से मैं नहीं जानता कि कैसे registerMetaDataForSelector समारोह काम करता है, और उस पर डॉक्स नहीं मिला है - मैं अभी भी एक ही त्रुटि मिलती है जब मैं अपने चयनकर्ता आह्वान नोड पर मैं स्ट्रॉ को एक char * में बदलने के लिए PyObjC कैसे कहूं? (या वहाँ यह करने के लिए एक बेहतर तरीका है के रूप में इन तार एक हेडर फाइल में #defined सी स्थिरांक हैं है।)


अद्यतन: मैं (उल्लेख in this blog post के रूप में) gen_bridge_metadata उपयोग करने की कोशिश, और, आदमी से परामर्श के बाद पृष्ठ ने निम्नानुसार प्रयास किया:

sudo mkdir -p /System/Library/PrivateFrameworks/DSObjCWrappers.framework/Resources/BridgeSupport 
sudo gen_bridge_metadata --framework ~/Downloads/DSTools-112.1/build/Deployment/DSObjCWrappers.framework/ --output /System/Library/PrivateFrameworks/DSObjCWrappers.framework/Resources/BridgeSupport/DSObjCWrappers.bridgesupport 

मुझे अभी भी वही त्रुटि मिलती है;

help(modules) 

मैं:

/System/Library/PrivateFrameworks/DSObjCWrappers.framework/Versions/A/Resources/<ipython console> in <module>() 

NameError: name 'modules' is not defined 

मैं भी है कि मैं प्रकार है कि मेरा मानना ​​है कि की एक सूची पाया उल्लेख करना चाहिए समझी जाती हो वहाँ कोई संकेत नहीं है कि यह भी देखा गया था, सिवाय इसके कि अगर मैं टाइप है रजिस्टर द्वारा MetaDataForSelector समारोह; objective-C type encodings। ध्यान दें कि विशेष कार्य के लिए एक्सएमएल मैं के बाद कहते हैं:

<method selector='hasRecordsOfType:'> 
<retval type='B'/> 
</method> 

मैं कुछ इनपुट पैरामीटर समझा उम्मीद भी है जाएगा।

+0

पास करने के लिए c_char_p का उपयोग करें सी-स्ट्रिंग (मेरा उत्तर देखें) –

उत्तर

2

मेरा मानना ​​है कि आप एक गैर यूनिकोड स्ट्रिंग पास करना चाहिए और उसके बाद निम्नलिखित हैं:

objc.registerMetaDataForSelector("DSoNode", 
           "hasRecordsOfType:", 
      dict(
       arguments = 
       { 
        2: dict(type=objc._C_PTR + objc._C_CHAR_AS_TEXT, 
          c_array_delimited_by_null=True, 
          type_modifier=objc._C_IN) 
       } 
      )) 

एक और पूरी NSString उदाहरण इस प्रकार है:

from AppKit import * 
from Foundation import * 
import objc 

def setupMetadata(): 
    objc.registerMetaDataForSelector("NSString", "stringWithCString:", 
     dict(
      arguments = 
      { 
       2: dict(type=objc._C_PTR + objc._C_CHAR_AS_TEXT, 
         c_array_delimited_by_null=True, 
         type_modifier=objc._C_IN) 
      } 
     )) 

def doTest(): 
    s = NSMutableString.stringWithString_(u"foo"); 
    NSLog(u"string[" + s + "]") 

    s2 = NSString.stringWithCString_("bar") 
    NSLog(u"string[" + s2 + "]") 

setupMetadata() 
doTest() 
+0

(बेले गए उत्तर के लिए खेद है)। यह वास्तव में लगता है कि यह सही रास्ते पर है। दोनों उदाहरणों के साथ, मुझे मिलता है: विशेषताइरर: 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता नहीं है '_C_CHAR_AS_TEXT' –

+0

वाहू! जब मैंने objc._C_CHR का उपयोग किया, यह काम करता है! मैं निलंबित करता हूं _C_CHAR_AS_TEXT, पीओओबीजेसी के एक संस्करण से आता है जो तेंदुए के साथ जहाजों की तुलना में नया होता है। –

0

आप की तरह hasRecordsOfType कॉल करनी होगी इसलिए:

from ctypes import * 

typeString = c_char_p('dsRecTypeStandard:ComputerLists') 
node.hasRecordsOfType_(typeString) 
+0

उत्तर के लिए धन्यवाद।जब मैं इसे आज़माता हूं, तो मुझे मिलता है: वैल्यूएरर: 'char' को डिप्थोनिफाइंग, 'c_char_p' मिला –

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