Cli*_*ore 5 pyobjc pointers objective-c char
我正在尝试使用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)
Run Code Online (Sandbox Code Playgroud)
这很好.现在,我想在我的节点(类DSoNode)上调用一个方法,使用此objective-c签名.
最明显的方法是不知道如何获取字符串并将其传递给char*:
node.hasRecordsOfType_("dsRecTypeStandard:ComputerLists")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/Users/clinton/<ipython console> in <module>()
ValueError: depythonifying 'char', got 'str' of 31
Run Code Online (Sandbox Code Playgroud)
看起来可以在python看到它时更改签名.我尝试了一些变化:
objc.registerMetaDataForSelector("DSoNode", "hasRecordsOfType_", dict( arguments={ 2+0: dict(type_modifier='n', type='^C') }))
Run Code Online (Sandbox Code Playgroud)
但是 - 坦率地说我不知道registerMetaDataForSelector函数是如何工作的,并且还没有找到文档 - 当我在节点上调用我的选择器时,我仍然会得到相同的错误.如何告诉PyObjC将字符串转换为char*?(或者有更好的方法,因为这些字符串是头文件中的C常量#defined.)
更新:我尝试使用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
Run Code Online (Sandbox Code Playgroud)
我仍然得到同样的错误; 没有迹象表明这甚至被注意到,除非我输入:
help(modules)
Run Code Online (Sandbox Code Playgroud)
我明白了:
/System/Library/PrivateFrameworks/DSObjCWrappers.framework/Versions/A/Resources/<ipython console> in <module>()
NameError: name 'modules' is not defined
Run Code Online (Sandbox Code Playgroud)
我还要提一下,我发现了一个类型列表,我相信registerMetaDataForSelector函数可以理解这些类型; Objective-C类型编码.请注意,我所关注的特定函数的XML说:
<method selector='hasRecordsOfType:'>
<retval type='B'/>
</method>
Run Code Online (Sandbox Code Playgroud)
我也期望解释输入参数的东西.
我相信您想要以下内容,然后应该传递一个非 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)
}
))
Run Code Online (Sandbox Code Playgroud)
更完整的 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()
Run Code Online (Sandbox Code Playgroud)