如何在 Visual Studio 中静态链接 FreeType2?

Posted

技术标签:

【中文标题】如何在 Visual Studio 中静态链接 FreeType2?【英文标题】:How to statically link FreeType2 in Visual Studio? 【发布时间】:2018-01-28 18:23:22 【问题描述】:

我通过选择 Debug Multithreaded/SingleThreaded 配置从 VS2017 中的源代码将 Freetype 2.9 构建到静态库中。貌似静态库放在freetype-2.9\objs\x64\Debug Static\freetype.lib中。

在 VS2017 中,在 Additional Library Directories 我添加了 freetype-2.9\objs\x64\Debug Static。 在 Additional Dependencies 中,我添加了 freetype.lib。并将 Runtime Library 设置为 MTd。 但是编译会引发链接器错误:

1>------ Build started: Project: HelloFreetype, Configuration: Debug x64 ------
1>Source.cpp
1>Source.obj : error LNK2019: unresolved external symbol __imp_FT_Init_FreeType referenced in function main
1>Source.obj : error LNK2019: unresolved external symbol __imp_FT_Done_FreeType referenced in function main
1>C:\Users\joaqo\Documents\HelloFreetype\x64\Debug\HelloFreetype.exe : fatal error LNK1120: 2 unresolved externals
1>Done building project "HelloFreetype.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Freetype 对预处理器有不寻常的用途,所以这里也是代码:

#include <ft2build.h>
#include FT_FREETYPE_H

int main(int argc, char **argv)

    FT_Library  library;
    int error = FT_Init_FreeType(&library);
    if (error) 
        printf("FreeType: Initilization error\n");
        exit(EXIT_FAILURE);
    
    FT_Done_FreeType(library);
    exit(EXIT_SUCCESS);

x86 平台、发布配置和/或将 Windows SDK 重新定位到 8.1(Freetype 也是使用 SDK 8.1 构建的)也会发生同样的错误。也尝试使用 Freetype 2.7.1 没有成功。并且尝试链接到动态库完全没有问题!

感谢您的帮助!

【问题讨论】:

你用__declspec(dllimport)定义FT_Init_FreeTypeFT_Done_FreeType,如果你想要静态库,这已经是错误的了。现在在freetype.lib 中搜索FT_Init_FreeType - 它以哪种形式出现在此处?可能是__imp_?FT_Init_FreeType@@... 的形式?它是声明为 c 还是 c++ 函数? 嗯,是的,我在某处看到 'imp' 与 dll 有关,如果我用 7zip 打开 freetype.lib ,我可以看到一些'FT_Init_FreeType'形式的符号,没有imp。所以是的,我想我应该链接到没有 imp 的符号。但是,我怎样才能告诉 VS 寻找正确的符号呢? freetype.lib 中的 exactly 是哪个名称? 'FT_Init_FreeType' ?没有任何?@ 符号?由__declspec(dllimport) 在函数声明中产生的__imp_ 前缀。删除它 freetype.lib 中,有一个文本文件,其中包含如下几行:´..\..\..\objs\Win32\Debug Static\ ftinit.obj _FT_Init_FreeType´ freetype.lib 中的符号名称必须与 HelloFreetype 中使用的符号名称完全相同__imp_FT_Init_FreeType 说你在 FT_Init_FreeType 的声明中使用了 __declspec(dllimport) - 删除它!之后这个错误必须消失,否则FT_Init_FreeType符号将无法解决。 _FT_Init_FreeType - 你确定前面有_ 吗?这个说一下你看看 x86 的 lib 文件。你也可以运行link.exe /dump /LINKERMEMBER &lt;path&gt;freetype.lib &gt; freetype.txt 并查看它的公共符号。我怎么说名字必须完全匹配。符号到符号。 【参考方案1】:

我按照步骤重现了相同的链接器错误,但使用的是 VS2013。在构建 FreeType 时,我注意到几个 C4273 编译器警告,如下所示:

1>..\..\..\src\base\ftinit.c(321): warning C4273: 'FT_Init_FreeType' : inconsistent dll linkage
1>          C:\libraries\freetype-2.9\include\freetype/freetype.h(1987) : see previous definition of 'FT_Init_FreeType'

为了解决这些编译器警告,我编辑了config/ftconfig.h FreeType 头文件。我更改了以下行,

#define FT_EXPORT( x )  __declspec( dllimport )  x

到,

#define FT_EXPORT( x ) extern x

然后重建 FreeType。进行这些更改后,不再出现链接器错误。

【讨论】:

【参考方案2】:

我认为 FreeType 2.9 中出现此问题的原因是由于 ftconfig.h 中 FT_EXPORT 的定义发生了变化。

// From ftconfig.h - FreeType 2.9
#ifndef FT_EXPORT
    #ifdef __cplusplus
    #define FT_EXPORT( x )  extern "C"  x
    #else
    #define FT_EXPORT( x )  extern  x
    #endif

    #ifdef _MSC_VER
        #undef FT_EXPORT
        #ifdef _DLL
        #define FT_EXPORT( x )  __declspec( dllexport )  x
        #else
        #define FT_EXPORT( x )  __declspec( dllimport )  x
        #endif
    #endif
#endif /* !FT_EXPORT */

注意 _MSC_VER 部分将如何撤消前面的定义。这个 _MSC_VER 块在早期版本的 FreeType 中不存在。

如果您只想构建一个静态库(无 DLL),则像这样删除 _MSC_VER 部分:

#ifndef FT_EXPORT
    #ifdef __cplusplus
    #define FT_EXPORT( x )  extern "C"  x
    #else
    #define FT_EXPORT( x )  extern  x
    #endif
#endif /* !FT_EXPORT */

【讨论】:

以上是关于如何在 Visual Studio 中静态链接 FreeType2?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改静态链接库中 const 字符串数组的 Visual Studio C++ 初始化序列

如何在静态库 (Visual Studio) 中嵌入图标 (.ico)

visual studio 2008 c++ 中怎样添加动态链接库?

从一个 Visual Studio 项目构建多个版本的静态库

在 Visual Studio 2010 上将静态库链接到我的项目

Visual Studio 2010 不会自动链接来自依赖项的项目中的静态库,因为它应该是