2009-08-12 29 views
5

Tôi đang cố gắng sử dụng một khung công tác riêng với PyObjC. Tôi đã có điều này cho đến thời điểm này:Gọi bộ chọn lấy một ký tự * từ PyObjC

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) 

Điều đó có hiệu quả. Bây giờ, tôi muốn gọi một phương thức trên nút của tôi (của lớp DSoNode), với chữ ký khách quan này.

  • (BOOL) hasRecordsOfType: (const char *) Intype

Cách rõ ràng nhất không biết làm thế nào để có một chuỗi và vượt qua nó để một char *:

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

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

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

Có vẻ như nó có thể thay đổi chữ ký như python nhìn thấy nó. Tôi đã thử một số các biến thể trên:

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

nhưng - và thẳng thắn Tôi không biết làm thế nào các chức năng registerMetaDataForSelector hoạt động, và đã không tìm thấy tài liệu trên đó - tôi vẫn nhận được lỗi tương tự khi tôi gọi chọn của tôi trên nút. Làm thế nào để tôi nói với PyObjC để chuyển đổi một chuỗi thành một char *? (Hoặc là có một cách tốt hơn để làm điều đó, vì đây là những chuỗi là C hằng #defined trong một tập tin tiêu đề.)


Cập nhật: Tôi cố gắng sử dụng gen_bridge_metadata (như đã đề cập in this blog post), và sau khi có ý kiến ​​của người đàn ông , hãy thử như sau:

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 

Tôi vẫn gặp lỗi tương tự; không có dấu hiệu cho thấy này thậm chí còn chú ý, ngoại trừ rằng nếu tôi gõ:

help(modules) 

tôi nhận được:

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

NameError: name 'modules' is not defined 

Tôi cũng nên đề cập đến mà tôi tìm thấy một danh sách các loại mà tôi tin rằng sẽ được hiểu bởi hàm registerMetaDataForSelector; objective-C type encodings. Lưu ý rằng XML cho hàm cụ thể mà tôi đang nói sau đây:

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

Tôi cũng đã mong đợi điều gì đó giải thích thông số đầu vào.

+0

Sử dụng c_char_p để vượt qua chuỗi c (xem câu trả lời của tôi) –

Trả lời

2

Tôi tin rằng bạn muốn những điều sau và sau đó phải vượt qua một chuỗi không unicode:

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) 
       } 
      )) 

Một hoàn chỉnh hơn ví dụ NSString sau:

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

(Xin lỗi vì câu trả lời muộn màng). Điều này thực sự có vẻ như nó đang đi đúng hướng. Với cả hai ví dụ, tôi nhận được: AttributeError: đối tượng 'module' không có thuộc tính '_C_CHAR_AS_TEXT' –

+0

Woohoo! Khi tôi sử dụng objc._C_CHR, nó hoạt động! Tôi nhạy cảm _C_CHAR_AS_TEXT xuất phát từ một phiên bản của PyObjC mới hơn so với phiên bản đi kèm với Leopard. –

0

Bạn phải gọi hasRecordsOfType như như vậy:

from ctypes import * 

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

Cảm ơn bạn đã trả lời. –

Các vấn đề liên quan