在按照Google's docs成功构建Pdfium之后,我用VS2022创建了一个新的C控制台应用程序,并尝试嵌入Pdfium构建产生的.lib
,但是,它导致了几个未解析的符号,我猜,这些符号应该包含在标准C中。作为一个示例,下面是两个未解析的符号:
fx_string.obj: error LNK2001: unresolved external symbol "void __cdecl std::Cr::__libcpp_verbose_abort(char const *,...)"
fpdf_parser_utility.obj : error LNK2001: unresolved external symbol "public: class std::Cr::basic_ostream<char,struct std::Cr::char_traits<char> > & __cdecl std::Cr::basic_ostream<char,struct std::Cr::char_traits<char> >::write(char const *,__int64)"
- 采取的步骤**:
- 使用以下
args.gn
在docs steps之后构建Pdfium:
use_goma = false
is_debug = false
pdf_use_skia = false
pdf_enable_xfa = false
pdf_enable_v8 = false
pdf_is_standalone = false
is_component_build = false
pdf_is_complete_lib = true
- 创建了一个简单的C++控制台应用程序,包含以下内容(复制自Getting started):
#include <iostream>
#include "../PDFium/public/fpdfview.h"
int main()
{
std::cout << "PDFium test!\n";
FPDF_LIBRARY_CONFIG config{};
config.version = 2;
config.m_pUserFontPaths = NULL;
config.m_pIsolate = NULL;
config.m_v8EmbedderSlot = 0;
FPDF_InitLibraryWithConfig(&config);
FPDF_DestroyLibrary();
return 0;
}
- 将Pdfium的公共文件夹和生成的
.lib
文件复制到项目的单独文件夹中,为链接器添加必要字段,并将 C++ 规范设置为stdc++20
;下面是.vcxproj
<!-- other tags -->
<ClCompile>
<!-- other tags -->
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
<!-- other tags -->
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)PDFium\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>PDFium.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
中的相应标记
- (不成功)测试*
- 尝试使用和不使用
pdf_is_complete_lib = true
编译PDFium,因此,也链接单个.obj
以及v8
和xfa
支持 - 尝试使用Microsoft的
clang-cl
而不是MSBuild
(Visual Studio的本机开发包提供的MSBuild
)进行编译 - 尝试使用仓库工具的
clang-cl
(当前版本为16.0.0
)进行编译 - 尝试了几个选项,发现在这里和那里的SO和互联网上
任何帮助都很感激。先谢了。
1条答案
按热度按时间lh80um4z1#
经过几天的失败和(徒劳的)研究,我终于找到了解决办法,张贴在这里供日后参考。
TL;DR;
根据
args.gn
中设置的标志,Pdfium将需要至少以下内容才能成功构建并启动Getting Started示例:is_component_build = false
以及pdf_is_complete_lib = true
、.obj
文件从libc++
和winmm.lib
构建is_component_build = true
,并且因此pdf_is_complete_lib = false
,所有.dll
都是编译得到的,即:absl.dll
icuuc.dll
partition_alloc.dll
pdfium.dll
zlib.dll
也请阅读下面的重要说明,它试图解释这两个标志之间的区别。
详细描述
根据文档,一旦
.ninja
文件作为gn args <out_dir>
的结果生成,就可以看到构建pdfium_unitests.exe
需要哪些.obj
、.lib
和.dll
文件。将这些文件与用于生成pdfium.lib
(或pdfium.dll
,取决于标志,见下文)的文件进行比较,就可以发现所需的库。对于
is_component_build = false
和pdf_is_complete_lib = true
:ninja -C <out_dir>
启动默认编译;这也构建了libc++;ninja -C <out_dir> pdfium
生成pdfium.lib
(将仅执行链接步骤)libc++.lib
,其中包含编译libc++时生成的所有.obj
文件:pdfium.lib
、项目中C:\out_dir\obj\buildtools\third_party\libc++\libc++
(或上一步中的libc++.lib
)和winmm.lib
中的所有libc++的.obj
文件;例如:对于
is_component_build = true
和pdf_is_complete_lib = false
:ninja -C <out_dir> pdfium
开始编译;我将编译所有必需的.dll
以及.pdb
和.lib
文件,并将它们放在out_dir
中pdfium.lib
,并在输出目录中复制发出的.dll
;假设发出的文件在C:\pdfium\result
中,项目的.vcxproj
将如下所示:注解:你需要的文件列在tl中; dr;截面。
注意2:使用
robocopy
,因为它比xcopy
更有效。此外,由于robocopy
返回的值,需要检查退出代码重要提示
pdf_is_complete_lib
和is_component_build
将在编译期间分别设置/MT
和/MD
标志。虽然看起来可能不是问题,但如果两种类型混合,MSBuild将发出警告,因此您需要重新编译Pdfium或通过 * 项目属性〉C/C++〉代码生成〉运行时库 * 更改代码生成方式。
有关详细信息,请参阅Google docs、Microsoft有关flags和linker warning的文档,最终还可参阅this SO question,这些文档可帮助您选择最适合您需要的代码生成。