2009-08-12 5 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) 

잘 작동한다. 자,이 objective-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 
    
    : 가장 확실한 방법은 문자열을하는 방법을 알고 숯불 *에 전달하지 않습니다

(CONST의 char *) INTYPE

파이썬에서 서명을 변경할 수있는 것처럼 보입니다. 나는에 약간의 변화를 시도 :

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> 

나는 입력 매개 변수에 대해서도 설명해 주었다.

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_p를 사용하여 C - 문자열 (내 대답 참조) –

답변

2

난 당신이 비 유니 코드 문자열을 전달해야 다음 다음과 원하는 믿는다 그래서 :

from ctypes import * 

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

(후회 회신 죄송합니다). 이것은 올바른 방향에있는 것처럼 보입니다. 두 예제 모두에서 다음을 얻습니다. AttributeError : 'module'객체에 '_C_CHAR_AS_TEXT'속성이 없습니다. –

+0

Woohoo! objc._C_CHR을 사용하면 작동합니다! 나는 _C_CHAR_AS_TEXT가 Leopard와 함께 제공되는 PyObjC 버전보다 최신 버전입니다. –

0

당신은 같은 hasRecordsOfType 전화를해야

+0

답장을 보내 주셔서 감사합니다.내가 그것을 시도 할 때, 나는 얻는다 : ValueError : 'char'를 depythonifying하고있다, 'c_char_p'을 얻었다. –