Aufrufen von Cocoa-APIs von C

Lesezeit: 3 Minuten

Ich weiß nicht, ob dies möglich ist, aber ist es mit Code in einfachem C möglich, Cocoa-APIs davon aufzurufen?
Etwas wie #include <cocoa.h>die entsprechende Bibliothek hinzufügen und loslegen?

Danke für die Hilfe

Benutzeravatar von ughoavgfhw
ughoavgfhw

Wenn Sie mit den Cocoa- oder Foundation-Frameworks verknüpfen, können Sie object-c in Ihrem C-Code verwenden. Wenn Sie jedoch die normale Messaging-Syntax verwenden möchten, müssen Sie die Dateierweiterung von .c in .m ändern, damit sie als Ziel-c kompiliert wird. Wenn Sie die Erweiterung .c beibehalten, können Sie nur die Laufzeitaufrufe im c-Stil verwenden, um mit Zielobjekten zu interagieren (dh objc_msgSend, objc_getClassetc.).

Beispiele: Innerhalb einer .m-Datei

void cFunction() {
    [[NSString alloc] init];
}

Innerhalb einer .c-Datei

void cFunction() {
    void* cls = objc_getClass("NSString");
    void* obj = objc_msgSend(cls, NSSelectorFromString(CFSTR("alloc")));
    obj = objc_msgSend(obj, NSSelectorFromString(CFSTR("init")));
}

Wenn Sie die zweite Methode wählen, lesen Sie die Objective-C-Laufzeitreferenz.

  • Im Allgemeinen anrufen objc_msgSend so wie es ist ist das falsche. Sie sollten es in einen geeigneten Funktionstyp umwandeln: typedef CFStringRef (*StringWithStringIMP)(id, SEL, CFStringRef); CFStringRef string = ((StringWithStringIMP)objc_msgSend)(objc_getClass("NSString"), sel_getUid("foo"), CFSTR("This is pointless."));

    – Jens Ayton

    5. Mai 2011 um 17:42 Uhr

  • Kühl. Wie mache ich das? Wie verlinke ich mit dem Cocoa- oder Foundation-Framework? auf Projektebene? kann ich #include es? Ich möchte weiterhin nur einfache C-Dateien und ein Makefile haben, um es zu kompilieren und zu verknüpfen (ohne mich dabei auf XCode zu verlassen).

    – Herr Aleph

    5. Mai 2011 um 17:47 Uhr

  • @MrAleph Sie müssen GCC anweisen, mit dem Framework zu verknüpfen. Verwenden -Xlinker -framework -Xlinker Foundation um dies zu tun. Du solltest tun #include <Foundation/NSObjcRuntime.h> um den aktuellen Runtime-Header zu erhalten.

    – ughoavgfhw

    5. Mai 2011 um 18:06 Uhr

  • @MrAleph: Ich rate dringend davon ab, es zu verwenden objc_msgSend aus .c Datei. Benutz einfach .m. Sie können eine kompilieren .m Datei ohne XCode, indem Sie gcc foo.m -o foo.o -framework Foundation -framework Cocoa usw.

    – Yuji

    5. Mai 2011 um 23:21 Uhr

Objective-C ist ein sehr dünner Wrapper auf C. Der Compiler übersetzt nur

 [obj message:argument];

in einen C-Anruf

 obj_msgSend(obj,@selector(message:),argument);

und das ist es (wo @selector(message:) ist eine magische Kodierung, die einen Selektor (Methodenname) in ein computerverständliches Ding verwandelt.)

Daher gibt es aus Sicht des Compilers keinen großen Unterschied zwischen Objective-C und C. Beispielsweise können Sie ein reines C-Programm mit einem Objective-C-Compiler kompilieren, mit genau dem gleichen Ergebnis wie beim Kompilieren mit einem C-Compiler.

Der einfachste Weg, ein bisschen Objective-C mit C zu “mischen”, ist die Verwendung .m -Erweiterung, sodass der Compiler Objective-C verwendet.

Das macht Ihr Programm nicht plötzlich sehr Objective-Cy. Mit der Erweiterung können Sie Ihr Programm fast in reinem C halten .m. Mit .mkönnen Sie problemlos ein paar Zeilen von Objective-C-Nachrichtenaufrufen hinzufügen.

  • Wäre ich in der Lage, ein einfaches Makefile zu schreiben, um dies zu kompilieren und zu verknüpfen?

    – Herr Aleph

    5. Mai 2011 um 17:51 Uhr

  • Es sind wirklich nur Quelldateien mit einem anderen Suffix und einem anderen Compiler-Aufruf. Die erstellten Objektdateien sind einfache Objektdateien, wie sie von reinen C-Compilern erstellt werden.

    – Freigebig

    5. Januar um 16:06 Uhr

1432420cookie-checkAufrufen von Cocoa-APIs von C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy