その問題を解決した後、私は新しい問題を抱えています:
状況: 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