【问题标题】:Unresolve external symbols when using v8.dll in my project在我的项目中使用 v8.dll 时未解析的外部符号
【发布时间】:2022-12-22 15:39:33
【问题描述】:

我是制作 C++ 项目的新手。我可能不确定 C++ 项目的先决条件知识。

[我的环境]

  • Windows 10
  • 蟒蛇 2.7.18
  • VS 2022 的开发人员命令提示符
  • Visual Studio 2022 社区

我目前正在努力将 V8 引擎制作成 DLL 并使用它。

我已成功将 V8 引擎构建为 DLL,但使用它时遇到“无法解析外部符号”错误。

细节:

error LNK2019: unresolved external symbol "class std::unique_ptr<class v8::Platform,struct std::default_delete<class v8::Platform> > __cdecl v8::platform::NewDefaultPlatform(int,enum v8::platform::IdleTaskSupport,enum v8::platform::InProcessStackDumping,class std::unique_ptr<class v8::TracingController,struct std::default_delete<class v8::TracingController> >)" (?NewDefaultPlatform@platform@v8@@YA?AV?$unique_ptr@VPlatform@v8@@U?$default_delete@VPlatform@v8@@@std@@@std@@HW4IdleTaskSupport@12@W4InProcessStackDumping@12@V?$unique_ptr@VTracingController@v8@@U?$default_delete@VTracingController@v8@@@std@@@4@@Z) referenced in function "public: __cdecl ezv8::Platform::Impl::Impl(void)" (??0Impl@Platform@ezv8@@QEAA@XZ)

我研究了一些 C++ 处理和编译器行为的东西。

我注意到 v8_libplatform.dll.lib 文件包含其他类型的损坏符号,如下所示。

?NewDefaultPlatform@platform@v8@@YA?AV?$unique_ptr@VPlatform@v8@@U?$default_delete@VPlatform@v8@@@__1@std@@@__1@std@@HW4IdleTaskSupport@12@W4InProcessStackDumping@12@V?$unique_ptr@VTracingController@v8@@U?$default_delete@VTracingController@v8@@@__1@std@@@45@@Z = ?NewDefaultPlatform@platform@v8@@YA?AV?$unique_ptr@VPlatform@v8@@U?$default_delete@VPlatform@v8@@@__1@std@@@__1@std@@HW4IdleTaskSupport@12@W4InProcessStackDumping@12@V?$unique_ptr@VTracingController@v8@@U?$default_delete@VTracingController@v8@@@__1@std@@@45@@Z (class std::__1::unique_ptr<class v8::Platform,struct std::__1::default_delete<class v8::Platform> > __cdecl v8::platform::NewDefaultPlatform(int,enum v8::platform::IdleTaskSupport,enum v8::platform::InProcessStackDumping,class std::__1::unique_ptr<class v8::TracingController,struct std::__1::default_delete<class v8::TracingController> >))

如您所见,.lib 文件包含带有 __1 命名空间的符号。

我发现了为什么该文件包含该文件。捆绑的 clang 编译器使用内联命名空间 __1 编译 std 命名空间,但我不确定如何在没有 __1 内联命名空间的情况下更改编译。

有谁知道如何改变编译器的行为?

【问题讨论】:

    标签: c++ visual-studio clang v8 ninja


    【解决方案1】:

    我自己解决了这个问题。 (但我在构建过程中仍然遇到其他错误。)

    问题是我必须向gn args 添加一个标志“is_clang = false”,因为绑定 v8 的 clang 会将其他类型的 manglings 编译为 MSVS。

    如果我添加了标志,那么 v8 工具将使用您安装的 cl.exe 编译这些代码。

    【讨论】:

      【解决方案2】:

      这个问题在谷歌搜索结果中,所以我加了五分钱。

      我与v8::platform::NewDefaultPlatform()函数以及v8::Context::Scope::Scope()v8::Context::Scope::~Scope()等其他一些方法有完全相同的链接问题。原因与名称修改无关,看起来 clang-cl(在 Windows 平台上默认在 v8/chromium 中使用)使用与 cl 相同的名称修改。所有这些方法都在头文件中定义,因此它们是有效的内联,并且 clang-cl 使用 /Zc:DllexportInlines- 编译器选项,它不会从 DLL 中导出内联(有关详细信息,请参阅 https://reviews.llvm.org/D51340?id=172304)。

      很早以前就有人提出要给cl编译器添加/Zc:DllexportInlines选项的请求:https://developercommunity.visualstudio.com/t/implement-zcdllexportinlines-aka-fvisibility-inlin/374754,但截至目前,cl版本19.34.31937仍然不支持。

      所以我看不出在不修改 v8/chromium 头文件的情况下将 v8 DLL 与 Microsoft 的 cl 编译器一起使用的方法(这从来都不好)。可以将 v8 构建为静态库,或使用 clang-cl 作为自定义构建工具。

      至于使用is_clang=falsegn 参数在没有 clang 的情况下构建 v8,我想知道它是否真的可能。有许多编译器选项,如 -Wno-unused-const-variable-Wno-unused-function,它们不受 cl 支持,但在 gn 构建文件中无条件添加。我记得几年前可以使用 cl 构建铬,但现在可以了吗?

      【讨论】: