Frage

Ich versuche, einen privaten Rahmen mit PyObjC zu verwenden. Ich habe dies so weit gekommen:

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)

Das funktioniert gut. Nun möchte ich eine Methode auf meinem Knoten nennen (der Klasse DSoNode), mit diesem Ziel-c Signatur.

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

Der offensichtlichste Weg nicht weiß, wie eine Zeichenfolge zu nehmen und es zu einem Zeichen passieren *:

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

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

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

Es sieht aus wie es möglich ist, die Signatur zu ändern, wie Python es sieht. Ich habe versucht, einige Varianten zu:

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

aber - und ehrlich gesagt weiß ich nicht, wie die registerMetaDataForSelector Funktion funktioniert, und haben nicht docs darauf gefunden - ich immer noch die gleichen Fehler, wenn ich meine Wähler auf dem Knoten aufzurufen. Wie kann ich PyObjC sagen einen String in einen char * zu konvertieren? (Oder gibt es einen besseren Weg, es zu tun, wie diese Strings sind C Konstanten in einer Header-Datei #defined.)


Update: Ich habe versucht gen_bridge_metadata mit (als a href erwähnt <= "http://www.friday.com/bbum/2007/10/27/pyobjc-20-pyobjc-in-leopard/" rel = "nofollow noreferrer "> in diesem Beitrag Blog), und nach der man-Seite Anhörung versuchte es wie folgt:

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

ich immer noch die gleichen Fehler; es gibt keine Anzeichen dafür, dass dies auch bemerkt wurde, mit der Ausnahme, dass, wenn ich ein:

help(modules)

ich:

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

NameError: name 'modules' is not defined

Ich sollte auch erwähnen, dass ich eine Liste der Arten gefunden, die ich glaube, durch die registerMetaDataForSelector Funktion verstanden würde; Objective-C-Typ-Codierungen . Beachten Sie, dass die XML für die jeweilige Funktion sagt, ich bin nach:

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

Ich habe erwartet etwas, um die Eingabeparameter zu erklären, zu.

War es hilfreich?

Lösung

Ich glaube, Sie die folgende wollen und dann ein Nicht-Unicode-String übergeben sollte:

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

Ein vollständigere NSString Beispiel folgt:

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

Andere Tipps

Sie haben hasRecordsOfType zu nennen etwa so:

from ctypes import *

typeString = c_char_p('dsRecTypeStandard:ComputerLists')
node.hasRecordsOfType_(typeString)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top