C ++项目编译为静态库,失败(链接器错误)作为动态库。为什么?

时间:2010-05-17 11:23:15

标签: c++ dll visual-studio-2008-sp1 log4cplus

我有一个VS2008本机C ++项目,我希望将其编译为DLL。

它只引用一个外部库(log4cplus.lib),并使用其功能。 (当然也使用log4cplus的.h文件)。

当我尝试将项目编译为静态库时,它会成功。 当我尝试DLL时,它失败了:

1>MessageWriter.obj : error LNK2019: unresolved external symbol "public: static class log4cplus::Logger __cdecl log4cplus::Logger::getInstance(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (?getInstance@Logger@log4cplus@@SA?AV12@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z) referenced in function "class log4cplus::Logger __cdecl Log(void)" (?Log@@YA?AVLogger@log4cplus@@XZ)

还有4个与log4cplus.lib中的函数相关的错误。

看起来真的很蠢......请帮帮我:)。

谢谢!

编辑:

我链接到log4cplus.lib文件,它发现它很好。 另外,log4cplus.lib是100%功能的,我在另一个项目中使用它没有任何问题。 我的初衷是将我的项目编译为静态库并在我正在编写的另一个DLL中使用它,但是当这样做时,我在其他项目中得到了相同的链接器错误......

编辑#2:

导致链接器错误的函数是静态函数..这可能是问题的一部分吗?

7 个答案:

答案 0 :(得分:6)

wilx是对的。我有相同的链接问题。

我花了将近一天的时间来解决这个问题。

我已经下载了log4cplus-1.0.4,用Visual Studio 2010打开这个项目后,编译它,静态和动态库,没有错误。

但是,当我尝试使用这些库时,无论是静态库还是动态库,都会出现链接错误。

原因是,默认情况下,那些项目使用多字节字符,但是,我自己的项目使用unicode,因此,为了解决这些链接问题,你只需要更改一个项目的字符集。

unicode或两个多字节字符集。

并在visual studio 2010中更改一个项目的字符集, 请参阅以下链接。

How do I turn off Unicode in a VC++ project?

答案 1 :(得分:4)

当您创建静态库时,库创建者不会尝试解析您正在使用的所有函数(log2cplus.lib中的函数)。创建与静态库链接的可执行文件时,将解析这些函数。

当您创建动态库时,库创建者(链接器)会尝试解析您正在使用的所有函数。一旦构建动态库,就必须为链接器提供log4cplus.lib库。您不能等到创建可执行文件。

答案 2 :(得分:3)

在任何一种情况下,您都需要链接库。

区别在于,当您静态链接时 - 所有功能都通过您正在使用的库链接。

当您动态链接时,您链接到导入库,该库具有加载和使用dll功能的功能,此步骤您将丢失。通常,导入库的名称与您链接的dll的名称相同。

编辑:

我看到缺少的符号不是'__imp ......' 这意味着未对动态链接“配置”头文件,可能是因为您在项目中未定义LOG4CPLUS_BUILD_DLLlog4cplus_EXPORTSDLL_EXPORT,其中包含Log4Cplus标头。

答案 3 :(得分:2)

您实际上是否正在使用log2cplus.lib文件进行链接?如果您正在编译为静态库,那么您将通过最终的.exe而不是静态库链接到它 - 也许这就是区别?

答案 4 :(得分:0)

您使用了__declspec(dllimport)和__declspec(dllexport)吗?

链接静态库时不需要它们,但DLL需要它们。必须声明该函数用于导出(在DLL中),因此用户可以在外部使用它(从而从DLL导入它)。

也许这会有所帮助:

使用__declspec(dllimport)导入应用程序

http://msdn.microsoft.com/en-us/library/8fskxacy%28VS.80%29.aspx

最好的问候

答案 5 :(得分:0)

如果您正在使用像MSVC这样的编译器,那么在从lib更改为dll时,它可能已经更改了项目设置而您不知道它。您应该仔细检查在DLL模式下,您已正确链接到lib。

答案 6 :(得分:0)

我可以看到链接器错误的两种可能性:

  1. 您已使用提供的版本构建配置编译了log4cplus.dll(以及关联的log4cplus.lib导入库),但现在您的应用程序编译时将“字符集”选项设置为“使用Unicode字符集”< / p>

  2. 或者您正在尝试使用log4cplus的静态库,但为您的应用程序定义了LOG4CPLUS_BUILD_DLL。

  3. 我打赌数字1.它可能是别的,仍然。您使用的是什么版本的log4cplus?

    如果要在应用程序中使用log4cplus.dll,请定义LOG4CPLUS_BUILD_DLL符号。 log4cplus_EXPORTS和DLL_EXPORT分别只支持基于CMake的构建系统和基于autotools的构建系统。