1

我认为动态库(以及 Apple 的 Mach-O 框架的扩展)的一个特性是在使用的应用程序被链接之前保留一些符号(方法)未定义,但似乎必须解析所有符号clang++才能成功构建框架。

例如,在构建飞行模拟框架时,可能会留下一个名为aeroundefined 的 C 例程(但具有“extern aero()”规范)。但 XCode 4.2 拒绝构建框架,称其_aero为“未定义符号”。

这是 Objective-C 和 ANSI-C 例程包含的头文件:

// FlightVehicleCAdapter_data.h

#ifndef FlightVehicleCAdapter_data_h
#define FlightVehicleCAdapter_data_h

#ifdef __cplusplus
external "C" {
#endif

extern void aero( void );

#ifdef __cplusplus
}
#endif

这里是它被调用的地方:

// FlightVehicleCAdapter.m

-(void) calcAero {
    aero();
    [self setBodyAeroForce_lb:   [lsVector3 vectorFromScalarX:fv_data->f_aero_v.x
                                                            Y:fv_data->f_aero_v.y
                                                            Z:fv_data->f_aero_v.z]];
    [self setBodyAeroMoment_ftlb:[lsVector3 vectorFromScalarX:fv_data->m_aero_v.x
                                                            Y:fv_data->m_aero_v.y
                                                            Z:fv_data->m_aero_v.z]];

}

我曾希望能够aero()在应用程序中定义链接该框架的真实例程,但是当尝试构建框架本身时,链接器拒绝在没有具体aero()实现的情况下构建它:

Undefined symbols for architecture [i386|x86_64]:
  "_aero", referenced from:
    -[FlightVehicleCAdapter calcAero] in FlightVehicleCAdapter.o

所以我然后定义了一个虚拟aero()例程:

// dummy_aero.c
// not showing fv_data structure definition for clarity

void aero(void){
    fv_data->f_aero_v.x = 0.0; 
    fv_data->f_aero_v.y = 0.0;
    fv_data->f_aero_v.z = 0.0;

    fv_data->m_aero_v.x = 0.0;
    fv_data->m_aero_v.y = 0.0;
    fv_data->m_aero_v.z = 0.0;
}

这个定义aero()满足clang++了Mach-O框架(动态库)的构建成功。但是,当我将生成的框架与包含非平凡aero()例程的应用程序目标链接时,将调用框架的虚拟aero()对象而不是应用程序的aero().

4

2 回答 2

3

您需要将-bundle_loader <executable>选项传递给链接器,尽管我不确定它是否适用于框架。或者,您可以使用-undefined dynamic_lookup.

于 2012-05-19T10:43:53.433 回答
2

您需要为 aero() 执行此操作:

#ifdef __cplusplus
extern "C" {
#endif

extern void aero( void );

#ifdef  __cplusplus
}
#endif

这确保函数在 C++ 中声明为具有 C 可解析的名称。C++ 构建名称的方式与 C 不同。

请注意,然后 aero() 可以在运行时链接。

于 2012-05-19T00:21:08.783 回答