2013-05-19 10 views
5

Ich stehe hier ein seltsames Problem, ich versuche, die libkml C++ project sources in mein iOS-Projekt zu integrieren. Innerhalb des Projektes wurde unabhängig in Ordnung, aber wenn es um die Verknüpfung durch diese Codezeile kommt:Symbole nicht für Architektur gefunden i386 - Aber funktioniert für iOS-Gerät

kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude); 

I Linker Fehler erhalten Erst als ich es bin Gebäude für Simulator. Es funktioniert gut, wenn ich es für iOS-Gerät zu bauen, aber für Simulator ich die folgenden 3 Linker Fehler erhalten:

(null): "kmldom::GxTimeSpan::GxTimeSpan()", referenced from: 

(null): Kmldom::KmlFactory::CreateGxTimeSpan() const in libLibKML.a(kml_factory.o) 

(null): "kmldom::GxTimeStamp::GxTimeStamp()", referenced from: 

(null): Kmldom::KmlFactory::CreateGxTimeStamp() const in libLibKML.a(kml_factory.o) 

(null): Symbol(s) not found for architecture i386 

(null): Linker command failed with exit code 1 (use -v to see invocation) 

These errors occur only when I try to build for simulator

ich mit der Entwicklung für das Gerät allein in Ordnung sein könnte, aber ich bin auf der Suche dieses Problem zu beheben Problem aus 2 Gründen:

  1. Wäre es einfach für das Team Simulator zu Entwicklungszwecken zu verwenden.
  2. Ich möchte wirklich auf den Grund davon gehen und verstehen, warum das im ersten Fall passiert. Warum es für Gerät baut und für Simulator fehlschlägt, obwohl das Ziel das selbe ist und die Quelldateien, die im Ziel enthalten sind, das gleiche über Simulator sowie Gerät wären?.

Die Definition von GXTimeStamp und GXTimeSpan Klassen sind in der Datei gx_timeprimitive.h Header und dies ist der Inhalt:

#ifndef KML_DOM_GX_TIMEPRIMITIVE_H__ 
#define KML_DOM_GX_TIMEPRIMITIVE_H__ 

#include <string> 
#include "kml/base/xml_namespaces.h" 
#include "kml/dom/kml22.h" 
#include "kml/dom/object.h" 
#include "kml/dom/timeprimitive.h" 

namespace kmldom { 

class Serializer; 
class Visitor; 

// <gx:TimeSpan> 
class GxTimeSpan : public TimeSpan { 
public: 
    virtual ~GxTimeSpan(); 
    static KmlDomType ElementType() { 
    return Type_GxTimeSpan; 
    } 
    virtual KmlDomType Type() const { return Type_GxTimeSpan; } 
    virtual bool IsA(KmlDomType type) const { 
    return type == Type_GxTimeSpan || TimeSpan::IsA(type); 
    } 

    // Visitor API methods, see visitor.h. 
    virtual void Accept(Visitor* visitor); 

private: 
    friend class KmlFactory; 
    GxTimeSpan(); 
    LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTimeSpan); 
}; 

// <gx:TimeStamp> 
class GxTimeStamp : public TimeStamp { 
public: 
    virtual ~GxTimeStamp(); 
    static KmlDomType ElementType() { 
    return Type_GxTimeStamp; 
    } 
    virtual KmlDomType Type() const { return Type_GxTimeStamp; } 
    virtual bool IsA(KmlDomType type) const { 
    return type == Type_GxTimeStamp || TimeStamp::IsA(type); 
    } 

    // Visitor API methods, see visitor.h. 
    virtual void Accept(Visitor* visitor); 

private: 
    friend class KmlFactory; 
    GxTimeStamp(); 
    LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTimeStamp); 
}; 

} // end namespace kmldom 

#endif // KML_DOM_GX_TIMEPRIMITIVE_H__ 

ich viele Beiträge gelesen, dass Linkerfehler auftreten Coz die Quelldateien nicht kompiliert werden . Ich habe in den gleichen Zeilen gedacht, um dieses Problem zu lösen, aber ich kann diese Header-Datei nicht in kompilierte Quellen aufnehmen, weil es eine .h-Datei ist.

Auch doppelt Ich habe - kml_factory.cc-Datei wird in den Kompilierung Quellen des inneren Projekt enthalten:

kml_factory.cc file included in compile phase

Wir freuen uns für Anregungen und Hilfe. Vielen Dank.

+0

Welche Version von XCode verwenden Sie? –

+0

Ich verwende 4.6.2 –

Antwort

3

Macht mich dumm, dies zu sagen, aber ich weiß nicht, wie die gx_timeprimitive.cc-Datei fehlte. Ich hatte den Eindruck, dass gx_timeprimitive.h-Datei von selbst vollständig war, wie es virtuelle Klassen hat, und ich versuchte, die GXTimeSpan und GXTimeStamp Klassen zu definieren, indem die leere Implementierung von Konstrukteuren in privaten Rahmen bieten, wie folgt aus:

class GxTimeSpan : public TimeSpan { 
public: 
    virtual ~GxTimeSpan(); 
    static KmlDomType ElementType() { 
    return Type_GxTimeSpan; 
    } 
    virtual KmlDomType Type() const { return Type_GxTimeSpan; } 
    virtual bool IsA(KmlDomType type) const { 
    return type == Type_GxTimeSpan || TimeSpan::IsA(type); 
    } 

    // Visitor API methods, see visitor.h. 
    virtual void Accept(Visitor* visitor); 

private: 
    friend class KmlFactory; 
    GxTimeSpan() 
    { 

    } 
    LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTimeSpan); 
}; 

Aber dennoch würde der Compiler nicht erstellen Objektdatei aus Schnittstellendateien (.h-Dateien werden von Kompilierquellen ausgeschlossen, sie enthalten nur alle Deklarationen). Daher kann der Linker die benötigten Konstruktoren nicht finden. Dies veranlasste mich, die Datei gx_timeprimitive.cc im Internet zu suchen und sie war tatsächlich verfügbar.

Denken mit coolem Kopf hätte mir 100 Bounty Points gerettet, aber ich habe eine Lektion zu tragen!

Auch zu beantworten, warum es Fehler im Simulator-Modus allein geben wurde: Eigentlich erwähnte die Linie, die ich oben - kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude); wenn für ARMv7 gebaut, glaube ich, dass es sei denn, die Variable appPoint an anderer Stelle des Linker im Code verwendet wird, Überspringt die Verknüpfung mit den Quellen der Objektdatei von libkml. Dagegen würde i386 eine Verknüpfung unabhängig davon ausführen, ob die Variable im Code verwendet wird oder nicht. Ich denke, das ist eine Art Compiler-Optimierung, aufgrund derer das Verhalten in den jeweiligen Architekturen unterschiedlich ist. Es war dieses Puzzle, das mir den entscheidenden Hinweis verpasste, in die fehlende Datei zu schauen!

Entschuldigung für diejenigen, die sich Zeit nahmen, um dieses dumme Problem von mir zu lösen, danke euch allen.

2

Dies könnte etwas ähnlich wie iOS symbols not found for architecture i386 sein.

Hier sind die wichtigsten Punkte:

Wenn Bibliotheken bauen, Frameworks oder Anwendungen für iOS, XCode nur Objektcode für die Architekturen kompiliert für das Ziel in den Build-Einstellungen festgelegt. XCode verbindet auch nur mit Binärdateien, die die angegebene Architektur haben.

Wenn Sie Code im iOS-Simulator ausführen, führen Sie Ihren Code auf Ihrem Desktop aus, der die i386-Architektur ist.

Wenn Sie den fehlenden i386-Architekturfehler beim Ausführen einer iOS-Anwendung im simluator erhalten, müssen Sie sicherstellen, dass Ihre Anwendung und alle abhängigen Bibliotheken für die i386-Architektur erstellt wurden.

+0

Ich habe den Quellcode libkml in meinem Code enthalten, was bedeutet, dass die Bibliothek libkml für die Architektur erstellt wird, die vor dem Erstellen des Hauptprojekts ausgewählt wurde. Außerdem hängt libkml nur von einer externen Bibliothek ab - Expat library, die ich extern kompiliert habe und eine fat-Bibliothek erstellt wurde, die sowohl über i386 als auch über ARMv7 verbunden werden kann. Außerdem gibt die Expat-Bibliothek hier kein Problem, wie in meiner Frage angegeben, liegt das Problem irgendwo im Quellcode von libkml-Quellen. Ich versuche immer noch herauszufinden, was falsch ist, danke für deine Vorschläge. –

Verwandte Themen