如何在Windows 10上使用g ++编写静态C ++库并将其链接到可执行文件?

问题描述

main.cpp

#include <iostream>

int main() {
    std::cout << "main()" << std::endl;
    foo();
    return 0;
}

foo.cpp

#include <iostream>

extern "C" {
  void foo() {
      std::cout << "bar" << std::endl;
  }
}

编译静态库:

$ g++ foo.cpp -static

错误

undefined reference to `WinMain'

但这会编译:

$ g++ foo.cpp -shared -o foo.lib

现在我有一个名为foo.lib的静态库(据说)。

我尝试编译链接到它的可执行文件

$ g++ -L -lfoo main.cpp -o main.exe

并得到此错误

'foo' was not declared in this scope

但是foo在我要链接的静态库中声明。如果该链接有效,那么我也不需要在 main.cpp 中声明它。那么,为什么链接不起作用?


更新。

我在 main.cpp 添加void foo();,所以它不会抱怨foo需要声明。

#include <iostream>

void foo();

int main() {
    std::cout << "main()" << std::endl;
    foo();
    return 0;
}

所以我尝试再次编译,然后得到这个新错误

undefined reference to `foo()'

为什么我需要在 main.cpp 中定义foo?它已经在静态库 foo.cpp 中定义。

如果我必须在 main.cpp 中定义foo,那么就无法实现链接到库 foo.lib 的全部目的。

更新

  • 删除所有extern "C" { ... }行不会使“ foo未定义”错误消失。

解决方法

以下是您寻求的魔咒:

  • main.cpp
#include <iostream>
extern void foo();
int main() { 
  std::cout << "main()" << std::endl; 
  foo();
} 
  • foo.cpp
#include <iostream>
void foo() { 
  std::cout << "bar" << std::endl; 
}

控制台命令:

$ g++ -o foo.obj -c foo.cpp
$ ar rcs foo.lib foo.obj
$ g++ main.cpp foo.lib -o main.exe

这些拼写将静态库 foo 与可执行文件 main 静态链接在一起。