C++项目编译为静态库,编译为动态库失败(链接器错误)。为什么?
我有一个 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:
导致链接器的函数错误是静态函数..这可能是问题的一部分吗?
I've a VS2008 native C++ project, that I wish to compile as a DLL.
It only references one external library (log4cplus.lib), and uses its functions.
(also uses log4cplus's .h files , naturally).
When I try to compile my project as a static library, it succeeeds.
When I try as DLL, it fails :
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)
There are 4 more errors just like this related to functions within log4cplus.lib.
It seems like something really stupid.. please help me :)
Thanks!
Edit :
I am linked against the log4cplus.lib file, and it finds it just fine.
also, the log4cplus.lib is 100% functional, I am using it in another project with no problems.
My original intention was to compile my project as a static library and use it in another DLL I am writing, but when do this, I get the same linker errors in that other project...
Edit #2 :
The functions which cause the linker errors are static functions.. could this be part of the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
wilx 是对的。我也有同样的链接问题。
我花了将近一天的时间才解决这个问题。
我下载了log4cplus-1.0.4,用Visual Studio 2010打开这个项目后,编译它,静态库和动态库都没有错误。
但是,当我尝试使用这些库时,无论是静态库还是动态库,我都会遇到链接错误。
原因是,默认情况下,这些项目使用多字节字符,但是,我自己的项目使用unicode,因此,要解决这些链接问题,您只需更改一个项目的字符集即可。
均为 unicode 或多字节字符集。
并在 Visual Studio 2010 中更改一个项目的字符集,
请参阅以下链接。
如何在 VC++ 项目中关闭 Unicode?< /a>
wilx is right.I have the same link problem.
it took me almost one day to slove this issue.
I have downloaded log4cplus-1.0.4, after I opened this project with visual studio 2010,compile it, both static and dynamic library, no error.
however, when I try to use those library, I got a link error,no matter static library or dynamic library.
the reason is,by default, those project use multi-byte character, however, my own project use unicode,so,to slove those link problem, you just need to change one project's charset.
both unicode or both multi-byte charset.
and to change one project's charset in visual studio 2010,
see the following link.
How do I turn off Unicode in a VC++ project?
当您创建静态库时,库创建者不会尝试解析您正在使用的所有函数(log2cplus.lib 中的函数)。当您创建与静态库链接的可执行文件时,这些函数就会得到解决。
当您创建动态库时,库创建者(链接器)确实会尝试解析您正在使用的所有函数。构建动态库后,您必须立即向链接器提供 log4cplus.lib 库。您不能等到创建可执行文件。
When you're creating a static library, the library creator does not try to resolve all the functions that you are using (the ones that are in log2cplus.lib). These functions are resolved when you create an executable that links with your static library.
When you're creating a dynamic library, the library creator (the linker) does try to resolve all the functions you are using. You have to provide the linker with the log4cplus.lib library as soon as you build the dynamic library. You cannot wait until you create the executable.
在任何一种情况下,您都需要链接到库。
不同之处在于,当您静态链接时 - 所有功能都通过您正在使用的库链接。
当您动态链接时,您会链接到导入库,该库具有加载和使用 dll 中的函数的功能,而您缺少此步骤。通常导入库与您链接的 dll 具有相同的名称。
编辑:
我看到缺少的符号不是“__imp ...”
这意味着头文件未“配置”为动态链接,可能是因为您在项目中未定义
LOG4CPLUS_BUILD_DLL
或log4cplus_EXPORTS
或DLL_EXPORT
包括 Log4Cplus 标头。In either case you need to link against library.
Difference is that when you link statically - all functionality is linked via library you're using.
When you're linking dynamically you link against import library which have functionality to load and use functions from dll and this step you're missing. Usually import library have the same name as the dll you're linking against.
Edit:
I saw it that missing symbol is not '__imp...'
This means that header file is not "configured" for dynamic linkage, probably because you have
LOG4CPLUS_BUILD_DLL
orlog4cplus_EXPORTS
orDLL_EXPORT
not defined in project where you include Log4Cplus headers.您实际上正在链接 log2cplus.lib 文件吗?如果您编译为静态库,那么您将通过最终的 .exe 链接到它,而不是在静态库中 - 也许这就是区别?
Are you actually linking with the log2cplus.lib file? If you were compiling as a static library then you would link to it via the final .exe and not in the static library - perhaps that is the difference?
您使用了 __declspec(dllimport) 和 __declspec(dllexport) 吗?
链接静态库时不需要它们,但 DLL 需要它们。该函数必须声明为导出(在 DLL 中),以便用户可以在外部使用它(从而从 DLL 导入它)。
也许这可以帮助:
使用 __declspec(dllimport) 导入应用程序
http://msdn.microsoft.com/en-us/library/8fskxacy%28VS.80%29.aspx
致以诚挚的问候
Did you use __declspec(dllimport) and __declspec(dllexport)?
They are not necessary when linking static libraries, but required for DLLs. The function has to be declared for exporting (in the DLL), so users can use it outside (and thus import it from the DLL).
Maybe this can help:
Importing into an Application Using __declspec(dllimport)
http://msdn.microsoft.com/en-us/library/8fskxacy%28VS.80%29.aspx
best regards
如果您使用像 MSVC 这样的编译器,那么当从 lib 更改为 dll 时,它可能会在您不知情的情况下更改项目设置。您应该在 DLL 模式下仔细检查是否已正确链接到该库。
If you're using a compiler like MSVC, then it may have changed the project settings without you knowing about it when changing from lib to dll. You should double-check that in DLL mode, you are properly linked to the lib.
我可以看到链接器错误有两种可能性:
您已使用提供的发布构建配置编译了 log4cplus.dll(以及关联的 log4cplus.lib 导入库),但现在您的应用程序是使用“字符集”编译的选项设置为“使用 Unicode 字符集”
或者您尝试使用 log4cplus 的静态库,但为您的应用程序定义 LOG4CPLUS_BUILD_DLL。
我赌第一。但也可能是别的东西。您使用的是哪个版本的 log4cplus?
如果要在应用程序中使用 log4cplus.dll,请定义 LOG4CPLUS_BUILD_DLL 符号。 log4cplus_EXPORTS 和 DLL_EXPORT 仅用于分别支持基于 CMake 的构建系统和 MingGW 上基于 autotools 的构建系统。
There are two possibilities that I can see for the linker error:
You have compiled the log4cplus.dll (and the associated log4cplus.lib import library) using the provided Release build configuration but now your application is compiled with "Character Set" option set to "Use Unicode Character Set"
Or you are trying to use log4cplus' static library but defining LOG4CPLUS_BUILD_DLL for your application.
I bet on number 1. It could be something else, still. What version of log4cplus are you using?
If you want to use log4cplus.dll in your application, define the LOG4CPLUS_BUILD_DLL symbol. log4cplus_EXPORTS and DLL_EXPORT are there only to support the CMake based build system, and autotools based build system on MingGW respectively.