链接器工具警告 LNK4049

已导入在“filename.obj”中定义的符号“symbol”

为符号指定了 __declspec(dllimport),即使该符号是在同一映像中的对象文件 filename.obj 中定义的。 删除 __declspec(dllimport) 修饰符以解决此警告。

备注

当在一个目标文件中定义某个符号并在另一个目标文件中使用 __declspec(dllimport) 声明修饰符引用该符号时,链接器将生成此警告。

警告 LNK4049 是更通用的链接器工具警告 LNK4217 版本。 如果链接器无法确定哪个函数或目标文件引用了导入的符号,链接器将生成警告 LNK4049。

生成 LNK4049 而不是 LNK4217 的常见情况是:

若要解析 LNK4049,请尝试执行以下过程之一:

  • 从触发 LNK4049 的符号的转发声明中删除 __declspec(dllimport) 修饰符。 可以使用 DUMPBIN 实用工具在二进制图像中搜索符号。 DUMPBIN /SYMBOLS 切换显示图像的 COFF 符号表。 有关 DUMPBIN 实用工具的详细信息,请参阅 DUMPBIN 参考

  • 暂时禁用增量链接和整个程序优化。 重新编译后,应用程序将生成警告 LNK4217,其中包括引用导入的符号的函数的名称。 从导入的符号中删除 __declspec(dllimport) 声明修饰符并根据需要重新启用增量链接或整个程序优化。

尽管最终生成的代码行为正确,但为调用导入函数而生成的代码比直接调用该函数的效率更低。 使用 /clr 选项进行编译时,不会出现此警告。

有关导入和导出数据声明的详细信息,请参阅 dllexport、dllimport

示例

链接以下两个模块将生成 LNK4049。 第一个模块生成一个包含单个导出函数的目标文件。

// LNK4049a.cpp
// compile with: /c

__declspec(dllexport) int func()
{
   return 3;
}

第二个模块生成一个目标文件,其中包含对第一个模块中导出的函数的转发声明,以及在 main 函数中对该函数的调用。 如果将此模块与第一个模块链接,将生成 LNK4049。 从声明中删除 __declspec(dllimport) 修饰符以解决警告。

// LNK4049b.cpp
// compile with: /link /WX /LTCG LNK4049a.obj
// LNK4049 expected

__declspec(dllimport) int func();
// try the following line instead
// int func();

int main()
{
   return func();
}

另请参阅

链接器工具警告 LNK4217
链接器工具警告 LNK4286
dllexport、dllimport