Raj*_*dal 5 c++ cocoa-touch cross-compiling ios ios6
我在这里面临一个奇怪的问题,我正在尝试将libkml C++项目源集成到我的iOS项目中.项目独立编译很好,但是当涉及通过这行代码链接时:
kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude);
Run Code Online (Sandbox Code Playgroud)
我得到链接器错误只有当我为模拟器构建它时.当我为iOS设备构建它时,它工作正常,但对于模拟器,我得到以下3个链接器错误:
(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)
Run Code Online (Sandbox Code Playgroud)

我可以单独开发设备,但我希望解决这个问题有两个原因:
GXTimeStamp和GXTimeSpan类的定义在头文件gx_timeprimitive.h中,这是内容:
#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__
Run Code Online (Sandbox Code Playgroud)
我读过很多帖子,链接器错误发生,因为源文件没有编译.我也在考虑同样的问题来解决这个问题,但我不能将这个头文件包含在编译源中,因为它是一个.h文件.
另外,我仔细检查 - kml_factory.cc文件包含在内部项目的编译源中:

期待提出建议和帮助.谢谢.
这么说让我觉得很愚蠢,但是,我不知道 gx_timeprimitive.cc 文件是如何丢失的。我的印象是 gx_timeprimitive.h 文件本身是完整的,因为它具有虚拟类,并且我尝试通过在 Private 范围内提供构造函数的空实现来定义 GXTimeSpan 和 GXTimeStamp 类,如下所示:
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);
};
Run Code Online (Sandbox Code Playgroud)
但是,编译器仍然不会从接口文件中创建目标文件(.h 文件被排除在编译源之外,它们只包含所有声明),因此链接器无法找到它所需的构造函数。这让我在互联网上搜索 gx_timeprimitive.cc 文件,它确实可用。
冷静思考可以为我节省 100 个赏金点,但我有一个教训!
另外,要回答为什么它仅在模拟器模式下给出错误:实际上我上面提到的那一行 -
kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude);
当为 ARMv7 构建时,我认为,除非该变量appPoint在代码中的其他地方使用,否则链接器会跳过将其与 libkml 对象的源链接文件。然而,无论代码中是否使用变量,i386 都会执行链接。我想这是某种编译器优化,因此在各自的体系结构中行为有所不同。正是这个谜题让我错过了调查丢失文件的关键线索!
对于那些花时间解决我这个愚蠢问题的人表示歉意,谢谢大家。