2009-08-12 7 views
5

私はPyObjCでプライベートフレームワークを使用しようとしています。私はこれまでこれを持っています:PyObjCから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) 

それはうまくいきます。さて、私はこの目的のC署名を使って(クラスDSoNodeの)自分のノード上のメソッドを呼びたいと思います。

  • (BOOL)hasRecordsOfType:

    node.hasRecordsOfType_("dsRecTypeStandard:ComputerLists") 
    --------------------------------------------------------------------------- 
    ValueError        Traceback (most recent call last) 
    
    /Users/clinton/<ipython console> in <module>() 
    
    ValueError: depythonifying 'char', got 'str' of 31 
    
    :最も明白な方法は、文字列を取る方法を知っているとのchar *に渡していない

(のconst char型*)INTYPE

pythonが見ているように署名を変更することができるようです。私は上のいくつかのバリエーションを試してみました:

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

しかし - と率直に言って、私はregisterMetaDataForSelector機能がどのように動作するか分からない、その上にドキュメントを発見していない - 私は私のセレクタを起動するとき、私はまだ同じエラーを取得しますノード上でPyObjCに文字列をchar *に変換するように指示するにはどうすればよいですか?男と協議した後、私は(in this blog postを述べたように)gen_bridge_metadataを使用してみました、そして:


更新(。または、これらの文字列は、ヘッダファイルで、#defineで定義Cの定数であるとして、それを行うには良い方法は、あります)次のように試してみました。

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 

私も、私は信じているタイプのリストを見つけたことを言及する必要がありますが、理解されるであろう、私が入力するとことを除いて、これは、でも注目されたことは示されていませんregisterMetaDataForSelector関数で指定します。 objective-C type encodings。関数のXMLは、次のように書いてあることに注意してください。

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

私は入力パラメータについても説明しています。私はあなたが次のことをしたいと、非ユニコード文字列を渡す必要があると考えてい

+0

c_char_pを使用してCの文字列(私の答えを参照) –

答えて

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

(後悔返信のため申し訳ありません)。これは本当に正しいトラックのようです。どちらの例でも、私は次のようになります:AttributeError: 'module'オブジェクトに '_C_CHAR_AS_TEXT'属性がありません –

+0

Woohoo! objc._C_CHRを使用したときに動作します。私は_C_CHAR_AS_TEXTがLeopardに付属しているものより新しいPyObjCのバージョンに由来することを認めています。 –

0

あなたはhasRecordsOfTypeなどを呼び出す必要がありますso:

from ctypes import * 

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

返事をありがとう。私はそれを試してみると、私は得る: ValueError: 'char'をdepythonifying、 'c_char_p' –

関連する問題