我正在尝试将私有框架与 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)
这很好用。现在,我想用这个objective-c 签名在我的节点(DSoNode 类)上调用一个方法。
- (BOOL) hasRecordsOfType:(const char*) inType
最明显的方法不知道如何获取字符串并将其传递给 char*:
node.hasRecordsOfType_("dsRecTypeStandard:ComputerLists")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/Users/clinton/<ipython console> in <module>()
ValueError: depythonifying 'char', got 'str' of 31
看起来可以更改 python 看到的签名。我尝试了一些变化:
objc.registerMetaDataForSelector("DSoNode", "hasRecordsOfType_", dict( arguments={ 2+0: dict(type_modifier='n', type='^C') }))
但是——坦率地说,我不知道 registerMetaDataForSelector 函数是如何工作的,也没有找到关于它的文档——当我在节点上调用我的选择器时,我仍然遇到同样的错误。如何告诉 PyObjC 将字符串转换为 char*?(或者有没有更好的方法,因为这些字符串是 C 常量 #defined 在头文件中。)
Update: I tried using gen_bridge_metadata
(as mentioned in this blog post), and, after consulting the man page, tried it as follows:
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
I still get the same error; there is no indication that this was even noticed, except that if I type:
help(modules)
I get:
/System/Library/PrivateFrameworks/DSObjCWrappers.framework/Versions/A/Resources/<ipython console> in <module>()
NameError: name 'modules' is not defined
I should also mention that I found a list of types that I believe would be understood by the registerMetaDataForSelector function; objective-C type encodings. Note that the XML for the particular function I'm after says:
<method selector='hasRecordsOfType:'>
<retval type='B'/>
</method>
I would've expected something explaining the input parameter, too.