G ++ / C ++无法链接库

时间:2017-03-07 14:33:29

标签: c++ compilation g++

我正在尝试使用C ++创建和链接静态库。我有两个文件:
helloWorld.cpp

#include <iostream>

  int main(int argc, char const *argv[]) {
  std::cout << "I'm inside main." << '\n';
  printHello();
  return 0;
}

libraryHello.cpp

#include <iostream>

void printHello() {
  std::cout << "Hello" << '\n';
}

我正在运行此类命令(基于http://www.techytalk.info/c-cplusplus-library-programming-on-linux-part-one-static-libraries/):

g++ -Wall -c libraryHello.cpp -o libraryHello.o
ar rcs libmylib.a libraryHello.o
g++ -static helloWorld.cpp -L. -lmylib -o helloExecute

前两个顺利,当尝试编译主文件时出现这样的错误:

helloWorld.cpp: In function ‘int main(int, const char**)’:
helloWorld.cpp:5:14: error: ‘printHello’ was not declared in this scope

看起来它根本没有加载,也找不到printHello。在编译,链接或其他任何东西时,我有什么问题吗?我想要做的是使用静态库从main调用printHello()过程并将其链接到helloWorld.cpp。

我的编译器:g ++ 5.4.0,操作系统:Ubuntu 16.04 32位

3 个答案:

答案 0 :(得分:3)

您在使用前未声明该功能:

#include <iostream>

void printHello(); /// <-- this was missing    

int main(int argc, char const *argv[]) {
  std::cout << "I'm inside main." << '\n';
  printHello();
  return 0;
}

您拥有链接所需的一切,但不适合编译。一般的想法是这样的:编译器需要为您使用的每个函数提供声明。也就是说,它必须知道它的名字和签名。

编译器现在将检查函数调用是否对给定签名有效,并为函数调用留下占位符。链接器可以解析这些占位符并将其替换为被调用函数的实际地址。

因此,链接器必须为该函数找到匹配的定义,即实际的实现。如果您只是声明该函数,但忘记定义它,编译将很快成功,但链接器会抱怨未解析的引用。

这种拆分允许您独立编译不同的源文件:每个源文件都需要知道它使用的每个函数的声明,而不是定义。这足以让编译器确保调用者正确使用该函数。声明通常放在头文件中,以确保实现和调用者对函数签名的一致性有一致的了解,即使它们位于不同的源文件中。

答案 1 :(得分:2)

helloWorld.cpp

#ifndef LIBRARYHELLO_H
#define LIBRARYHELLO_H

void printHello();

#endif // LIBRARYHELLO_H

libraryHello.h(您需要添加此文件)

#include <iostream>
#include <libraryHello.h>
void printHello() {
    std::cout << "Hello" << '\n';
}

libraryHello.cpp

OSError: [Errno 13] Permission denied: '/Users/myusername/Library/Python/2.7'

答案 2 :(得分:0)

你仍然需要有

的前瞻性声明
 void printHello();
main()之前

否则编译器不知道应该如何调用该函数。

通常的方法是将其放入相应的头文件中,并将其包含在其他翻译单元中。