2013-03-12 44 views
1

的一些不列直插式方法解決問題that後,我有一個新問題:錯誤「未定義的引用」到圖書館

情況:我有一個使用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 

Start.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) 

(有一長串的o ˚F.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包含附帶而C犯規#include

+2

您使用哪個命令來編譯C代碼? – Sebivor 2013-03-12 11:50:51

+0

錯過了,對不起。請參閱我的編輯 – ollo 2013-03-12 12:03:16

+1

是否可以製作一個最小的,可編譯的測試用例包含以下內容:1.僅重現此問題的基本要素以及2.足夠的代碼(和命令)可以重現此問題,而無需猜測或填充空白?這樣我們可以確切地說出你做錯了什麼,並且更好地指引你朝着正確的方向前進。 – Sebivor 2013-03-12 12:11:15

回答

0

看來問題是由破碎的cmake列表造成的。經過幾次更改,我現在可以編譯。然而,這看起來很奇怪,因爲cmakelists中存在所有文件。

1

C++軋液名稱的所有文件的列表。 C++函數的東西裝飾得像

__someletters_function_name_

來生成C風格的名字改編,你應該使用extern "C" { ... }但要完全誠實的,我不知道如何與類交互,或包括您的庫C++項目。

+0

在我的代碼中使用了這個,但沒有將它插入到我的示例中。從C調用的所有函數都在這樣一個'extern「C」'塊(在頭文件中),但是這不起作用。 – ollo 2013-03-12 12:44:32