Verwenden von statischen C/C++-Bibliotheken von iPhone ObjectiveC Apps

Lesezeit: 6 Minuten

Benutzer-Avatar
Akusete

Ist es möglich, eine statische C-Bibliotheks-API zu haben, die C++ intern verwendet und dies vor Benutzern der Bibliothek verbirgt?

Ich habe eine portable C++-Bibliothek geschrieben, die ich statisch mit einer iPhone-Anwendung verknüpfen möchte.

Ich habe ein Xcode-Projekt mit der Vorlage „statische Bibliothek“ von Max OS X erstellt und die Quelle hinüber kopiert sowie einen C-Wapper (um mit Ausnahmen umzugehen) mit (extern „C“) geschrieben.

Ich versuche, die generierte Bibliothek (.a-Datei) in einer anderen Cocoa-iPhone-Anwendung zu verwenden.

Alles funktioniert gut, wenn ich die Erweiterungen (.mm) für die aufrufende ObjectiveC-Datei und (.cpp) für die Implementierungsklasse in der Bibliothek verwende.

Aber ich bekomme unaufgelöste Symbole beim Linken, wenn ich versuche, die Wrapper-Datei in eine (.c)-Erweiterung zu ändern, obwohl alle Wrapper-Funktionsdateien nur C-Funktionen sind.

Nur weil C++ intern in einer Bibliothek verwendet wird, bedeutet dies, dass es extern immer noch als C++-Programm behandelt werden muss. Lässt sich diese Abstraktion nicht irgendwie erzwingen?

Bearbeiten: Danke für die Antworten,

Ich hatte extern “C” verwendet, ich war mir nur nicht sicher, welche Konfigurationen im aufrufenden Projekt benötigt wurden. dh. wenn das aufrufende Projekt wissen müsste, ob es C ++ verwendet, oder unwissend sein und denken könnte, dass es sich um eine reine C-Bibliothek handelt.

Anscheinend kann ich das nicht und muss (.mm)-Dateien für meine ObjectiveC-Klassen verwenden.

  • Deklarieren Sie Ihre C-Bibliotheksfunktionen mit extern “C”?

    – Jason Coco

    18. Dezember 2008 um 5:32 Uhr

  • Akusete, Ihre Frage bezieht sich wirklich nicht auf Objective-C, sondern auf C/C++ und Tools. Ich denke, Ihr Problem ist, dass Sie die C++-Laufzeitunterstützung nicht verlinkt bekommen, weil Sie Xcode-Dinge verknüpfen, die Sie mit einer C-Anwendung verknüpfen. Taggen Sie nicht mit Obj-C, wenn im Q nichts spezielles über Obj-C steht

    – Jason Coco

    18. Dezember 2008 um 6:00 Uhr

  • Mein Fehler, ich wusste nicht, dass Sie es entfernt hatten.

    – Akusete

    18. Dezember 2008 um 6:01 Uhr

Es ist zu schwierig, dies in Kommentaren zu tun, also werde ich Ihnen nur schnell demonstrieren, was die Verknüpfungsprobleme sind, die Sie haben. Wenn Xcode auf Dateien trifft, verwendet es Build-Regeln basierend auf dem Suffix, um zu entscheiden, welcher Compiler verwendet werden soll. Standardmäßig verknüpft gcc die Dateien mit der Standard-C-Bibliothek, jedoch nicht mit der Standard-C++-Bibliothek. Archivdateien (statische Bibliotheken) haben überhaupt keine Verknüpfungsauflösung. Sie sind im Grunde ein Archiv von Objektdateien, die verknüpft werden müssen. Da Sie in Ihrem Projekt keine .mm- oder .cpp-Dateien haben, wird g++ nie aufgerufen und Ihre Dateien werden nie mit den Standardbibliotheken verknüpft. Um dies zu korrigieren, fügen Sie einfach die Standard-C++-Bibliotheken zu Ihren anderen Linker-Flags in Ihrem Xcode-Projekt hinzu, oder fügen Sie sie einfach der vordefinierten Option other flags als -l (z. B. -lstdc++) hinzu.

Hier ist eine kurze Demonstration:

stw.h:

#ifdef __cplusplus
extern "C"
#endif
void show_the_world(void);

stw.cpp:

#include <iostream>
#include "stw.h"
using namespace std;

extern "C" void show_the_world() {
  cout << "Hello, world!\n";
}

Erstellen Sie die Bibliothek:

$ g++ -c stw.cpp -o stw.cpp -O0 -g
$ ar rcs stw.a stw.o

Verwenden der Bibliothek aus einer C-Anwendung:

meineapp.c:

#include "stw.h"

int main() {
  show_the_world();
  return 0;
}

Erstellen der C-Anwendung:

$ gcc -o myapp myapp.c stw.a -lstdc++ -g -O0
$ ./myapp
Hello, world!
$

Wenn Sie versuchen, ohne -lstdc++ zu kompilieren, erhalten Sie alle ungelösten Probleme, da der C-Compiler absolut KEINE Ahnung hat, dass er mit der C++-Laufzeit verknüpfen sollte (und warum sollte er, richtig!?!?), Also müssen Sie dies hinzufügen manuell. Die andere Option, die Sie haben, besteht darin, die Erstellungsregel für Ihr Projekt zu ändern … anstatt Xcode gcc zum Erstellen von .c- und .m-Dateien verwenden zu lassen, sagen Sie ihm, dass es g++ verwenden soll, und Ihre Probleme werden behoben.

  • Danke für deine Hilfe, entschuldige bitte, dass ich dich irritiere. Ich bin etwas unwissend, wie die C++-Laufzeit funktioniert, und hatte zuvor immer g++ oder VC++ verwendet.

    – Akusete

    18. Dezember 2008 um 6:30 Uhr

  • ah, du bist überhaupt nicht irritierend 🙂 einfach alles in 300-Zeichen-Kommentaren zu machen, war …

    – Jason Coco

    18. Dezember 2008 um 6:40 Uhr

  • Das hat meinen Speck gerettet, als ich die FMOD-Bibliotheken in mein direktes Objective-C-Projekt einbrachte. Muss -lstdc++ einschließen, um Linkfehler zu beseitigen.

    – Batgar

    1. April 2010 um 18:10 Uhr

Sie sollten die Funktionen deklarieren, die sichtbar sein sollen extern "C". Ihre Signaturen müssen C-kompatibel sein, aber der Inhalt nicht (Sie können beispielsweise auf C++-Objekte zugreifen, aber Sie können sie nicht direkt übergeben; Zeiger sind in Ordnung). Die Symbole sind dann für jede C-kompatible Umgebung sichtbar.

BEARBEITEN: Und kompilieren Sie es als C++-Quelldatei, C hat nicht den Begriff der Sprachverknüpfung. Es gibt ein paar andere Fallstricke bei der Sprachverknüpfung (wie die Tatsache, dass all extern "C" Funktionen mit demselben Namen sind dieselbe Funktion, unabhängig vom Namensraum).

EDIT2: In der Kopfzeile können Sie nach dem Makro suchen __cplusplusund verwenden Sie diese, um sie für C++ bzw. andere Sprachen festzulegen (weil C++ erfordert extern "C" Erklärungen, und andere Sprachen werden sich wahrscheinlich darüber beschweren).

  • Danke, “als C++-Quelldatei kompilieren” bedeutet, dass ich immer noch eine (.mm) Objective C-Datei benötige, um sie zu verwenden, oder? ‘C hat nicht den Begriff der Sprachverknüpfung’ Ich denke, das bedeutet, wenn ich C++ irgendwo in einer Bibliothek habe, muss das Ganze als C++ kompiliert werden.

    – Akusete

    18. Dezember 2008 um 5:49 Uhr

Wenn Sie die C-Funktionen mit einem C++-Compiler kompilieren, werden im Grunde die Funktionsnamen verstümmelt und die C++-ABI verwendet.

Wenn Sie die Erweiterung *.cpp oder *.mm verwenden, verwenden Sie den C++-Compiler.

Was Sie tun möchten, ist, den Compiler zu zwingen, C-Funktionen mit unverfälschten Namen und unter Verwendung der C ABI zu generieren.

Sie können dies tun, indem Sie entweder:

  • Kompilieren Sie mit dem C-Compiler.
  • Kompilieren Sie mit dem C++-Compiler, stellen Sie jedoch sicher, dass Sie den Funktionsdeklarationen extern “C” voranstellen.

Eine beliebte Methode zum Einrichten der Header-Datei, sodass dieselbe Datei sowohl aus C- als auch aus C++-Quelldateien eingefügt werden kann, ist:

#ifndef HEADER_GUARD_1_H
#define HEADER_GUARD_1_H

#ifdef __cplusplus
extern "C" {
#endif

// Declare C function interface here.
int myFunc(int x,char*);

#ifdef __cplusplus
}
#endif

#endif 

  • Danke, ich verstehe die Verwendung von extern “C”, die Bibliothek funktioniert derzeit für C/C++/C# (mit Pinvoke), auf Win32-WindowsCE- und Linux-Plattformen. Ich bin mir jedoch nicht sicher, ob ich (.mm) im ObjectiveC-Code verwenden musste, wenn meine Schnittstelle C war.

    – Akusete

    18. Dezember 2008 um 5:52 Uhr

  • Das .mm zwingt es nur dazu, den C++-Compiler anstelle des C-Compilers zu verwenden. Objective C ist nur ein Wrapper auf diesen Sprachen (ich meine das nicht wörtlich).

    – Martin York

    18. Dezember 2008 um 16:37 Uhr

danke, für diese gute diskussion.

was ich getan habe ist:

1) Ich habe eine statische Lib mit der statischen Lib-Option von cocaotouch erstellt. Darin habe ich c/c++/obj-c all mix. Meine Exporte sind jedoch nur Obj-C-Klassen. Tatsächlich habe ich objc- zu c zu C++ verwendet.

2) Dann habe ich eine iPhone-App in X-Code proj erstellt. Ich habe die otherlink-Flags meinen Lib-Namen ( -lxyz ) hinzugefügt // Mein Lib-Name ist libxyz.a Ich habe den Lib-Suchpfad und den Header-Suchpfad hinzugefügt

3) dann habe ich kompiliert. Ich habe Fehler. sagt oeprator new, operator delete not found.

3) dann abgesehen von meinem appdelegate, view controller, fügte ich dummy cpp(.h, .cpp) hinzu… atestdummy.h atestdummy.cpp

4) dann baue ich wieder…

das hat funktioniert.

Also – alle Vorschläge, die sie früher gemacht haben, haben für mich funktioniert. Hauptgrund, es sei denn, Ihre App sieht eine .cpp-Datei .mm-Datei mit cpp-Code, verknüpft wird g ++ nicht verwenden.

Danke an alle. Ich habe das oben gelesen und mein Problem gelöst.

u Jungs sind gut zu teilen.

1370910cookie-checkVerwenden von statischen C/C++-Bibliotheken von iPhone ObjectiveC Apps

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

Privacy policy