visual C++链接器不能将外部符号与静态libcurl一起使用

visual C++ linker cant use external symbol with static libcurl

本文关键字:静态 libcurl 一起 符号 外部 链接 C++ 不能 visual      更新时间:2023-10-16

我有这个简单的C++代码。

#include <iostream>
#include <windows.h>
#include <Lmcons.h>
#define CURL_STATICLIB
#include <iostream>
#include <fstream>
#include <curl.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "curl\libeay32.lib")
#pragma comment(lib, "curl\openldap.lib")
#pragma comment(lib, "curl\ssleay32.lib")
#if defined _DEBUG
    #pragma comment(lib, "curl\lib\Debug\curllib_static.lib")
#else
    #pragma comment(lib, "curl\lib\Release\curllib_static.lib")
#endif
using namespace std;
int main()
{
    TCHAR name [ UNLEN + 1 ];
    DWORD size = UNLEN + 1;
    if (GetUserName( (TCHAR*)name, &size ))
        wcout << "Hello, " << name << "!n";
    else
        wcout << "Hello, unnamed person!n";
    CURL *curl;
    CURLcode res;
    curl_version();

    /* In windows, this will init the winsock stuff */ 
    curl_global_init(CURL_GLOBAL_ALL);
    /* get a curl handle */ 
    curl = curl_easy_init();
    if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
        just as well be a https:// URL if that is what should receive the
        data. */ 
    curl_easy_setopt(curl, CURLOPT_URL, "http://requestb.in/19l9fjg1");
    /* Now specify the POST data */ 
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
    /* Perform the request, res will get the return code */ 
    res = curl_easy_perform(curl);
    /* Check for errors */ 
    if(res != CURLE_OK)
        fprintf(stderr, "curl_easy_perform() failed: %sn",
                curl_easy_strerror(res));
    /* always cleanup */ 
    curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
    system("PAUSE");
    return 0;
}

我的目录树。

X
|   app.cpp
|   
+---curl
|   |   CHANGES
|   |   curl.exe
|   |   curllib.dll
|   |   libcurl_imp.lib
|   |   libeay32.dll
|   |   libeay32.lib
|   |   openldap.dll
|   |   openldap.lib
|   |   README
|   |   ssleay32.dll
|   |   ssleay32.lib
|   |   
|   +---docs
|   |   |   BINDINGS
|   |   |   [...]
|   |   |   VERSIONS
|   |   |   
|   |   +---examples
|   |   |       10-at-a-time.c
|   |   |       [...]
|   |   |       threaded-ssl.c
|   |   |       
|   |   ---libcurl
|   |           ABI
|   |           [...]
|   |           Makefile.in
|   |           
|   +---include
|   |   |   Makefile.am
|   |   |   [...]
|   |   |   README
|   |   |   
|   |   ---curl
|   |           curl.h
|   |           [...]
|   |           types.h
|   |           
|   +---lib
|   |   +---Debug
|   |   |       curllib.dll
|   |   |       curllib.lib
|   |   |       curllib_static.lib
|   |   |       
|   |   ---Release
|   |           curllib.dll
|   |           curllib.lib
|   |           curllib_static.lib
|   |           
|   ---src
|       +---DLL-Debug
|       |       curl.exe
|       |       curllib.dll
|       |       openldap.dll
|       |       
|       +---DLL-Release
|       |       curl.exe
|       |       curllib.dll
|       |       openldap.dll
|       |       
|       +---LIB-Debug
|       |       curl.exe
|       |       
|       ---LIB-Release
|               curl.exe
|               
+---Debug
|       app.obj
|       [...]
|       vc110.pdb
|       
---Release
        app.obj
        [...]
        vc110.pdb

这就是我的设定。

Linker -> General -> Additional library directories
    XcurllibRelease;Xcurl;%(AdditionalLibraryDirectories)
Linker -> Input -> Additional dependences
    $(ProjectDir)curllibDebugcurllib_static.lib;%(AdditionalDependencies)
VC++-Directories -> Include directories
    $(ProjectDir)curlincludecurl;$(IncludePath)
VC++-Directories -> Library directories
    $(ProjectDir)curllibRelease;$(LibraryPath)

**$(ProjectDir)是X**

错误

Error   2   error LNK2005: _calloc already defined in LIBCMT.lib(calloc.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   3   error LNK2005: _realloc already defined in LIBCMT.lib(realloc.obj). XMSVCRT.lib(MSVCR110.dll)  X
Error   4   error LNK2005: _free already defined in LIBCMT.lib(free.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   5   error LNK2005: _malloc already defined in LIBCMT.lib(malloc.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   6   error LNK2005: _strrchr already defined in LIBCMT.lib(strrchr.obj). XMSVCRT.lib(MSVCR110.dll)  X
Error   7   error LNK2005: _strchr already defined in LIBCMT.lib(strchr.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   8   error LNK2005: _fwrite already defined in LIBCMT.lib(fwrite.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   9   error LNK2005: ___iob_func already defined in LIBCMT.lib(_file.obj).    XMSVCRT.lib(MSVCR110.dll)  X
Error   10  error LNK2005: _strtoul already defined in LIBCMT.lib(strtol.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   11  error LNK2005: _memmove already defined in LIBCMT.lib(memmove.obj). XMSVCRT.lib(MSVCR110.dll)  X
Error   12  error LNK2005: _tolower already defined in LIBCMT.lib(tolower.obj). XMSVCRT.lib(MSVCR110.dll)  X
Error   13  error LNK2005: _atoi already defined in LIBCMT.lib(atox.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   14  error LNK2005: _isxdigit already defined in LIBCMT.lib(_ctype.obj). XMSVCRT.lib(MSVCR110.dll)  X
Error   15  error LNK2005: _isdigit already defined in LIBCMT.lib(_ctype.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   16  error LNK2005: _isspace already defined in LIBCMT.lib(_ctype.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   17  error LNK2005: __strtoi64 already defined in LIBCMT.lib(strtoq.obj).    XMSVCRT.lib(MSVCR110.dll)  X
Error   18  error LNK2005: _memchr already defined in LIBCMT.lib(memchr.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   19  error LNK2005: _fclose already defined in LIBCMT.lib(fclose.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   20  error LNK2005: _strtol already defined in LIBCMT.lib(strtol.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   21  error LNK2005: _sprintf already defined in LIBCMT.lib(sprintf.obj). XMSVCRT.lib(MSVCR110.dll)  X
Error   22  error LNK2005: _fflush already defined in LIBCMT.lib(fflush.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   23  error LNK2005: __errno already defined in LIBCMT.lib(dosmap.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   24  error LNK2005: __lseeki64 already defined in LIBCMT.lib(lseeki64.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   25  error LNK2005: _getenv already defined in LIBCMT.lib(getenv.obj).   XMSVCRT.lib(MSVCR110.dll)  X
Error   26  error LNK2005: _isalnum already defined in LIBCMT.lib(_ctype.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   27  error LNK2005: _isalpha already defined in LIBCMT.lib(_ctype.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   28  error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMT.lib(typinfo.obj).  XMSVCRT.lib(ti_inst.obj)   X
Error   29  error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMT.lib(typinfo.obj).    XMSVCRT.lib(ti_inst.obj)   X
Error   30  error LNK2005: __strdup already defined in LIBCMT.lib(strdup.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   31  error LNK2005: __close already defined in LIBCMT.lib(close.obj).    XMSVCRT.lib(MSVCR110.dll)  X
Error   32  error LNK2005: __fileno already defined in LIBCMT.lib(fileno.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   33  error LNK2005: __read already defined in LIBCMT.lib(read.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   34  error LNK2005: __strnicmp already defined in LIBCMT.lib(strnicmp.obj).  XMSVCRT.lib(MSVCR110.dll)  X
Error   35  error LNK1169: One or more multiply defined symbols found in.   X..ReleaseX.exe  X

如果我用上面的curllib.lib替换curllib_static.lib,我会得到一个libcurl.dll丢失的错误。

因为AND,因为我不想在我的目录中有额外的libcurl.dll,所以我使用静态libcurl。

如何解决

我正在将此libcurl与Microsoft Visual Studio 2012一起使用。http://curl.haxx.se/download/libcurl-7.19.3-win32-ssl-msvc.zip

像这样的问题在Visual C++中很常见,很难准确描述如何修复它们。你需要非常小心,真正了解你包括哪些库,但这里没有足够的信息来解决这个问题。

一个常见的原因是使用了错误的运行库。在VS中,这将是/MT和/MD开关之间的区别,但您似乎在使用makefile,因此这可能不适用。LIBCMT是一个多线程库,但看起来您可能也包含了另一个库。

我不建议使用#pragmas来包含链接库。把它们放在makefile中,这样你就可以在一个地方看到所有内容。

通常,在启用日志记录的情况下运行链接器可以准确地查看调用了哪些库

您的目录树和设置没有什么帮助,但一个包含makefile的最小完整项目可能会让这里的人诊断问题。

stackoverflow中有一个老问题,它会引发一个非常相似的问题,看看这里:

错误LNK2005:xxx已在MSVCRT.lib(MSVCR100.dll)C:\something\LIBCMT.lib(setlocal.obj)中定义

这里的另一个链接:

LIBCMTD.lib和MSVCRTD.lib 的LNK2005错误

我希望它能帮助你!