1

ダイナミックライブラリ(および拡張機能としてAppleのMach-Oフレームワーク)の機能の1つは、使用するアプリケーションがリンクされるまで一部のシンボル(メソッド)を未定義のままにすることだと思いましたがclang++、フレームワークを正常に構築するには、すべてのシンボルを解決する必要があるようです。

たとえば、フライトシミュレーションのフレームワークを構築する場合、aero未定義という名前の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;
}

このの定義は、Mach-Oフレームワーク(ダイナミックライブラリ)が正常に構築されることをaero()満たしています。しかし、結果のフレームワークを重要なルーチンclang++を含むアプリケーションターゲットにリンクすると、アプリケーションの代わりにフレームワークのダミーが呼び出されます。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 に答える