Я пытаюсь использовать частную фреймворк с PyObjC. У меня это до сих пор:Вызовите селектор, который принимает 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)
Это прекрасно работает. Теперь я хочу вызвать метод на моем узле (класса DSoNode) с этой целью-c-сигнатурой.
- (BOOL) hasRecordsOfType: (Const символ *) inType
Самый очевидный способ не знает, как взять строку и передать его в символ *:
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 константы с помощью #define в заголовочном файле.)
Обновление: Я попытался с помощью gen_bridge_metadata
(как уже упоминалось in this blog post), и после консультаций с человеком страницы, попробовал его следующим образом:
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>
я бы ожидал чего-то объясняющую входным параметром тоже.
Использовать c_char_p для передачи c-string (см. мой ответ) –