2013-03-12 47 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