【问题标题】:How to write a static C++ library and link it to an executable using g++ on Windows 10?如何在 Windows 10 上使用 g++ 编写静态 C++ 库并将其链接到可执行文件?
【发布时间】:2020-10-21 01:04:49
【问题描述】:

ma​​in.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 是在我链接的静态库中声明的。如果链接有效,我认为我也不需要在 ma​​in.cpp 中声明它。那么为什么链接不起作用?


更新。

我将void foo(); 添加到ma​​in.cpp,因此它不会抱怨需要声明foo

#include <iostream>

void foo();

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

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

undefined reference to `foo()'

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

如果我必须在 ma​​in.cpp 中定义 foo,这会破坏链接到库 foo.lib 的全部目的。

更新

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

【问题讨论】:

  • 该函数必须在调用该函数时声明。这就是 C++ 的工作原理。编译器必须知道函数的名称和所有参数的类型。链接发生在 编译之后。代码必须先编译。
  • 对于投票关闭这个的人,请删除您的帐户。我用最少的可重复示例写了一个非常清晰的问题。
  • @SamVarshavchik 我在 main.cpp 的顶部声明了 foo(请参阅我更新的帖子),但现在它抱怨 foo 未定义。如果我必须在 main.cpp 中定义foo,这会破坏链接的目的。
  • 不,它不会“破坏链接的目的”。链接到库并不能消除声明函数的需要。这就是为什么所有常用的库都带有声明库中所有函数的头文件的原因。如果与库链接的行为消除了在库中声明任何函数的需要,那么就不需要头文件了,对吗?而且由于在库中,foo() 是使用“C”链接定义的,那么您添加到 main.cpp 的声明也必须具有“C”链接,对吧?
  • 我按照您在第一条评论中的建议声明了该功能。现在它抱怨它没有被定义。我可以在 main.cpp 中声明它。我不同意在 main.cpp定义它;在 main.cppfoo.cpp 中定义 foo 违背了静态库 foo.cpp 的目的。

标签: c++ windows g++ static-libraries static-linking


【解决方案1】:

以下是你寻求的魔法咒语:

  • 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 和静态链接的可执行文件 ma​​in

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-16
    • 2023-03-03
    • 2018-12-28
    • 2013-06-24
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多