静态库中的MSVC符号可见性

时间:2018-01-04 16:01:29

标签: c visual-c++

我有一个从某些数据自动生成的C源文件:

#include <stdint.h>
size_t BlurKernel_size = 840;
unsigned char BlurKernel[] = {
0x06b, 0x65, 0x72, // ... etc
};

我使用

将其编译为目标文件
cl /nologo kernels_embedd.c /c /Fokernels_embedd.obj /W4 /O2 /MT

然后将其放入静态库

lib /nologo /OUT:kernels_embedd.lib kernels_embedd.obj

然后我将它链接到我的主程序(extern const char* BlurKernel; extern const size_t BlurKernel_size;):

link /nologo /OUT:main.dll /DLL main.obj kernels_embedd.lib /IMPLIB:main.lib

我收到错误

main.obj : error LNK2019: unresolved external symbol "char const * const BlurKernel" (?BlurKernel@@3PEBDEB) referenced in function "public: __cdecl BlendIop::BlendIop(class Node *)" (??0BlendIop@@QEAA@PEAVNode@@@Z)
main.obj : error LNK2019: unresolved external symbol "unsigned __int64 const BlurKernel_size" (?BlurKernel_size@@3_KB) referenced in function "public: __cdecl BlendIop::BlendIop(class Node *)" (??0BlendIop@@QEAA@PEAVNode@@@Z)
main.dll : fatal error LNK1120: 2 unresolved externals

但是,使用kernels_embedd.lib查看dumpbin,符号可用:

> dumpbin kernels_embedd.lib /symbols
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file kernels_embedd.lib

File Type: LIBRARY

COFF SYMBOL TABLE
000 00AA766F ABS    notype       Static       | @comp.id
001 00000000 SECT1  notype       Static       | .drectve
    Section length   45, #relocs    0, #linenums    0, checksum        0
003 00000000 SECT2  notype       Static       | .debug$S
    Section length   CC, #relocs    0, #linenums    0, checksum        0
005 00000000 SECT3  notype       Static       | .data
    Section length  358, #relocs    0, #linenums    0, checksum ABAE4B9B
007 00000000 SECT3  notype       External     | BlurKernel_size
008 00000010 SECT3  notype       External     | BlurKernel

String Table Size = 0x1F bytes

  Summary

        358 .data
          CC .debug$S
          45 .drectve

(使用kernels_embedd.obj查看dumpbin时,我得到相同的输出。

之前我已经成功地将此方法用于GCC。我在MSVC上做错了什么?

1 个答案:

答案 0 :(得分:2)

正如@IgorTandetnik指出的那样,这些符号需要以C方式表示,以避免C ++名称错误。

extern "C" unsigned char BlurKernel[];
extern "C" size_t BlurKernel_size;

一个重要的附注,用于纠正问题中的错误:BlurKernel被定义为一个数组,因此将其外部化是很重要的。使用unsigned char* BlurKernel不起作用(当指针被取消引用时导致访问冲突)。