将标题包含在main.cpp以外的文件中时链接器错误

时间:2017-03-31 15:00:40

标签: c++ xcode linker

我试图将一些实用程序函数和全局变量添加到我的代码中,这样我就可以在项目中的每个类中使用它们。我想使用.hpp文件来定义结束.cpp文件以实现。

这是这两个文件的摘要:

// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp


namespace utils {

    int global_variable1;

    int global_variable2;

    void utility_function1(...);

    void utility_function2(...);

    void utility_function3(...);
}

#endif /* utilities_hpp */

和实施:

// This is Utilities.cpp
#include "Utilities.hpp"


namespace utils {

    void utility_function1(...) {
        // Some code
    }


    void utility_function2(...) {
        // Some code
    }


    void utility_function3(...) {
        // Some code
    }

}

除了我的main.cpp文件,我还有另外两个类。我的main.cpp文件包含Class1.hpp标题,其中包含Class2.hpp标题。

现在我认为我可以在#include "Utilities.hpp"Class1.hpp中放置另一个Class2.hpp而没有任何问题,因为我已经在该标题中使用了警卫。问题在于,当我尝试这样做时,链接器会抛出这个错误:Apple Mach-O Linker (ld) Error Group - clang: error: linker command failed with exit code 1 (use -v to see invocation)我无法理解为什么或如何解决它。

我在macOS Sierra 10.12.4上使用Xcode 8.3。

我希望我能够解释我的问题,非常感谢你们。

2 个答案:

答案 0 :(得分:0)

您在标头中的全局变量上缺少extern关键字。因此,您正在定义它们,当您在两个不同的源模块中包含标头时会导致多个定义。

在标题文件(extern)中添加extern int global_variable1;后,您需要在.cpp文件中添加定义,您还可以在其中定义函数。

答案 1 :(得分:0)

您违反了“一个定义规则”。 global_variable1global_variable2应在标题中声明extern,并在一个翻译单元(可能是Utilities.cpp)中定义。

您已在多个翻译单元中包含的标头中定义了全局变量,因此在main.cpp中定义了utils::global_variable1,在Utilities.cpp中定义了一个global_variable1。说到链接时,链接器无法知道要使用哪个extern,因此会抛出错误。

要解决此问题,请在声明中添加// This is Utilities.hpp #ifndef utilities_hpp #define utilities_hpp namespace utils { extern int global_variable1; //^^^^^^ <-----HERE extern int global_variable2; //^^^^^^ <-----HERE void utility_function1(...); void utility_function2(...); void utility_function3(...); } #endif /* utilities_hpp */ 关键字,并在&#34; Utilities.cpp&#34;中添加定义:

Utilities.hpp:

// This is Utilities.cpp
#include "Utilities.hpp"

namespace utils {

    int global_variable1;  //<---- Definitions added
    int global_variable2;

    void utility_function1(...) {
        // Some code
    }

    void utility_function2(...) {
        // Some code
    }

    void utility_function3(...) {
        // Some code
    }
}

Utilities.cpp:

RNFetchBlob.fetch(
    'POST',
    'htttp://www.myserver.com/api/login',
    { 'Content-Type': 'application/json'}
)
.then(response => {
    console.log(response.json());
})