我知道这对极客来说似乎很基础.但我想说清楚.
当我想使用Win32 DLL时,通常我只需要调用像LoadLibrary()和GetProcAdderss()这样的API.但最近,我正在使用DirectX9进行开发,我需要添加d3d9.lib,d3dx9.lib等文件.
我听说LIB用于静态链接,DLL用于动态链接.
所以我目前的理解是LIB包含方法的实现,并在链接时静态链接作为最终EXE文件的一部分.虽然DLL在运行时动态加载,但不是最终EXE文件的一部分.
但有时候,DLL文件会附带一些LIB 文件,因此:
检查维基百科后,我记得这些LIB文件称为导入库.但我想知道它如何与我的主应用程序和动态加载的DLL一起工作.
正如RBerteig所说,LIB文件中存在一些与DLL一起出现的存根代码.所以调用序列应该是这样的:
我的主要应用 - > LIB中的stub - >真正的目标DLL
那么这些LIB应包含哪些信息?我能想到以下几点:
我对吗?还有什么吗?
顺便说一句:有没有可以检查导入库的工具?如果我能看到它,就不会再有疑惑了.
我刚刚被Visual Studio 2010(C++)发出的一些非平凡的警告殴打(而不是很难).
编译给出了以下输出:
1 Debug\is.obj:警告LNK4042:对象指定多次; 附加项忽略
1 Debug\make.obj:警告LNK4042:对象指定多次; extras忽略
1 Debug\view.obj:警告LNK4042:对象指定多次; extras忽略
1 identity.obj:错误LNK2019:未解析的外部符号void __cdecl test::identity::view(void)(?view @ identity @ test @@ YAXXZ)在函数中引用void __cdecl test::identity::identity(void)(?identity @ 0test @@ YAXXZ)
1 identity.obj:错误LNK2019:未解析的外部符号void __cdecl test::identity::make(void)(?make @ identity @ test @@ YAXXZ)在函数中引用void __cdecl test::identity::identity(void)(?identity @ 0test @@ YAXXZ)
1 range.obj:错误LNK2019:未解析的外部符号void __cdecl test::range::is(void)(?是@ range @ test @@ YAXXZ)在函数中引用void __cdecl test::range::range(void)(?range @ 0test @@ YAXXZ)
链接器错误总是很难调试...但是有未解决的引用,所以我检查了......但是源代码是格式良好的......最后它击中了我:
我的文件夹层次结构如下:
src/
identity/
is.cpp
make.cpp
view.cpp
range/ …Run Code Online (Sandbox Code Playgroud) c++ visual-studio-2010 visual-studio visual-c++ visual-c++-2010
Visual Studio有很多不同的加载项,请参阅Visual Studio库 .请分享您的经验和最爱.
作为动力,这里有一些我最喜欢的:
我正在使用DCMTK库来读取Dicom文件(医学图像处理中使用的图像格式.)我在编译这个DCMTK源代码时遇到了问题.DCMTK使用一些额外的外部库(zlib,tiff,libpng,libxml2,libiconv).我知道应该使用相同的代码生成选项生成所有库.
我已经下载了这些支持库的编译版本,这些库是使用"多线程DLL"运行时选项(/ MD)编译的.在DCMTK源代码的每个项目中,我确保运行时选项是"多线程DLL"(/ MD).但是我仍然遇到这些错误:
Error 238 error LNK2005: ___iob_func already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(_file.obj) dcmp2pgm
Error 239 error LNK2005: __lock_file already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(_file.obj) dcmp2pgm
Error 240 error LNK2005: __unlock_file already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(_file.obj) dcmp2pgm
Error 241 error LNK2005: __initterm_e already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(crt0dat.obj) dcmp2pgm
Error 242 error LNK2005: _exit already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(crt0dat.obj) dcmp2pgm
Error 243 error LNK2005: __exit already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(crt0dat.obj) dcmp2pgm
Error 244 error LNK2005: __cexit already defined in MSVCRT.lib(MSVCR100.dll) C:\dcmtk-3.5.4-src\CMakeBinaries\dcmpstat\apps\LIBCMT.lib(crt0dat.obj) …Run Code Online (Sandbox Code Playgroud) 如何在Visual Studio中为特定项目设置要搜索的DLL文件的路径?
现在我在环境path变量中设置它,但我想更好地控制它.
我知道这个.
从C++调用C函数:
如果我的应用程序是在C++中,我不得不从用C编写的库调用函数.那么我会使用
//main.cpp
extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.
Run Code Online (Sandbox Code Playgroud)
这不会破坏名称C_library_function,链接器会在其输入*.lib文件中找到相同的名称,问题就解决了.
从C ???调用C++函数
但是在这里我扩展了一个用C语言编写的大型应用程序,我需要使用一个用C++编写的库.C++的名称错误导致了麻烦.Linker抱怨未解决的符号.好吧,我不能在我的C项目中使用C++编译器,因为这会破坏很多其他东西.出路是什么?
顺便说一句,我正在使用MSVC
当我尝试编译此代码(VS2010)时,我收到以下错误:
error C3499: a lambda that has been specified to have a void return type cannot return a value
void DataFile::removeComments()
{
string::const_iterator start, end;
boost::regex expression("^\\s?#");
boost::match_results<std::string::const_iterator> what;
boost::match_flag_type flags = boost::match_default;
// Look for lines that either start with a hash (#)
// or have nothing but white-space preceeding the hash symbol
remove_if(rawLines.begin(), rawLines.end(), [&expression, &start, &end, &what, &flags](const string& line)
{
start = line.begin();
end = line.end();
bool temp = boost::regex_search(start, end, what, expression, flags);
return temp; …Run Code Online (Sandbox Code Playgroud) 我应该使用哪个函数将文本输出到Visual Studio中的"输出"窗口?
我试过printf()但它没有显示出来.
如果我遇到if (!this) return;应用程序中的旧代码,那么风险有多严重?这是一个危险的滴答作响的定时炸弹需要立即在应用程序范围内搜索并摧毁努力,还是更像是可以安静地留在原点的代码气味?
当然,我不打算编写执行此操作的代码.相反,我最近在我们的应用程序的许多部分使用的旧核心库中发现了一些东西.
想象一下,一个CLookupThingy类具有非虚拟 CThingy *CLookupThingy::Lookup( name )成员函数.显然,那些牛仔时代的程序员遇到了许多崩溃事件,其中NULL CLookupThingy *是从函数传递的,而不是修复数百个调用站点,他悄悄地修复了Lookup():
CThingy *CLookupThingy::Lookup( name )
{
if (!this)
{
return NULL;
}
// else do the lookup code...
}
// now the above can be used like
CLookupThingy *GetLookup()
{
if (notReady()) return NULL;
// else etc...
}
CThingy *pFoo = GetLookup()->Lookup( "foo" ); // will set pFoo to NULL without crashing
Run Code Online (Sandbox Code Playgroud)
我本周早些时候发现了这颗宝石,但现在我是否应该解决这个问题.这是我们所有应用程序使用的核心库.其中一些应用程序已经发送给数百万客户,它似乎工作正常; 该代码没有崩溃或其他错误.删除if !this查找函数将意味着修复数千个可能传递NULL的调用站点; 不可避免地会有一些人被遗漏,引入新的错误,这些错误将在未来一年的发展中随机出现.
所以除非绝对必要,否则我倾向于不管它. …
禁用生成的警告的最佳方法是什么_CRT_SECURE_NO_DEPRECATE,这样可以轻松恢复它们并且可以跨Visual Studio版本工作?
visual-c++ ×10
c++ ×9
c ×3
c++11 ×1
extern-c ×1
gcc ×1
lambda ×1
linker ×1
msvcr100.dll ×1
windows ×1