1

その問題を解決した後、私は新しい問題を抱えています:

状況: C++ で書かれたライブラリを使用する C プロジェクトがあります。C からは関数の呼び出ししかありませんが、これらの関数の実装にはクラスが使用されます。

詳細:

ライブラリはエラーなしでコンパイルされますが、C プロジェクトをコンパイルすると次のエラーが返されます。

...
Start.cpp:(.text+0x860): undefined reference to `InitialCondition::Load(std::string, bool)'
Start.cpp:(.text+0x227b): undefined reference to `InitialCondition::SetMachIC(double)'
...

全般的:

<calling library implementation>:(...): undefined reference to <a class>::<a method>

これは通常、ライブラリが欠落していることを示しますが、この場合、そのライブラリのほとんどの関数を使用できます。実装でいくつかのクラスが使用されている場合にのみ失敗します。

次に例を示します。

C++ ライブラリの場合:

Start.h

...

#ifdef __cplusplus
extern "C"
{
#endif

    void start();
    ...
#ifdef __cplusplus
}
#endif

開始.cpp

#include "Start.h"
#include "InitialCondition"

InitialCondition* initCond;

void start()
{
    // initCond is set somewhere here
    ...
    initCond->SetMachIC(1.0);     // (A) has no reference
    initCond->SetAlphaDegIC(2.0); // (B) has a reference
}

InitCondition.h

// includes etc.

class InitialCondition : public ABaseClass
{
public:

    void SetMachIC(double mach);

    void SetAlphaDegIC(double a)
    {
        // inline implementation
    }   
};

C からの呼び出し:

#include "Start.h"

void example()
{
    start();
}

ライブラリは を使用してビルドされているためcmake、関連する部分は次のCMakeLists.txtとおりです。

set(INITIALISATION_SRC InitialCondition.cpp)
set(INITIALISATION_HDR InitialCondition.h)

add_library(Init ${INITIALISATION_HDR} ${INITIALISATION_SRC})
set_target_properties (Init PROPERTIES
                            VERSION "${LIBRARY_VERSION}")

if(BUILD_SHARED_LIBS)
  set_target_properties (Init PROPERTIES
                              SOVERSION ${LIBRARY_SOVERSION}
                              FRAMEWORK ON)
endif()

install(TARGETS Init LIBRARY DESTINATION lib
                     ARCHIVE DESTINATION lib
                     RUNTIME DESTINATION lib
                     # For Mac
                     FRAMEWORK DESTINATION "/Library/Frameworks")
install(FILES ${INITIALISATION_HDR} DESTINATION include/Project/initialization)

(私がこれを少し短くした.cppとファイルの長いリストがあります).h

注:ところで。このようなエラーのない、行以外のメソッド呼び出しがまだいくつかあります。

注:このファイルはサブディレクトリにあります。を使用して追加されましたadd_subdirectory(initialization)

注: nmコンパイル済みライブラリのリストには以下が含まれます。InitialCondition9SetMachICEd

ライブラリがリンクされていて、メソッドの実装が利用可能であっても、C から呼び出されたときにこれらのメソッドの参照がないのはなぜですか?


編集:

C で使用されるコマンドは次のとおりです。

コンパイル:

gcc -I"<include dir>" -O0 -g -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Test.d" -MT"src/Test.d" -o "src/Test.o" "../src/Test.c"

リンク:

gcc -L"<searchpath>" -shared -o "libTest.dll"  ./src/Test.o   -l<library name> -lstdc++

Test.dに含まれるすべてのファイルのリストが含まれています#include

4

2 に答える 2

1

C++ は名前をマングルしますが、C はそうではありません。C++ 関数は次のようなもので装飾されています

__someletters_function_name_

C スタイルの名前マングリングを取得するには、使用する必要がありますextern "C" { ... }が、正直なところ、それがクラスやライブラリを含む C++ プロジェクトとどのように相互作用するかはわかりません。

于 2013-03-12T12:35:40.637 に答える
0

問題はcmakeリストの破損が原因のようです。いくつかの変更の後、私は今両方をコンパイルすることができます。ただし、すべてのファイルがcmakelistに存在していたため、これは私には本当に奇妙に見えます。

于 2013-03-13T14:46:44.630 に答える