【问题标题】:C++ linker cant use external symbol with static libcurlC++ 链接器不能使用带有静态 libcurl 的外部符号
【发布时间】:2014-10-27 23:01:24
【问题描述】:

我有这个简单的 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: %s\n",
                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
    X\curl\lib\Release;X\curl;%(AdditionalLibraryDirectories)
Linker -> Input -> Additional dependences
    $(ProjectDir)curl\lib\Debug\curllib_static.lib;%(AdditionalDependencies)
VC++-Directories -> Include directories
    $(ProjectDir)curl\include\curl;$(IncludePath)
VC++-Directories -> Library directories
    $(ProjectDir)curl\lib\Release;$(LibraryPath)

**$(ProjectDir) 是 X**

错误。

Error   2   error LNK2005: _calloc already defined in LIBCMT.lib(calloc.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   3   error LNK2005: _realloc already defined in LIBCMT.lib(realloc.obj). X\MSVCRT.lib(MSVCR110.dll)  X
Error   4   error LNK2005: _free already defined in LIBCMT.lib(free.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   5   error LNK2005: _malloc already defined in LIBCMT.lib(malloc.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   6   error LNK2005: _strrchr already defined in LIBCMT.lib(strrchr.obj). X\MSVCRT.lib(MSVCR110.dll)  X
Error   7   error LNK2005: _strchr already defined in LIBCMT.lib(strchr.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   8   error LNK2005: _fwrite already defined in LIBCMT.lib(fwrite.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   9   error LNK2005: ___iob_func already defined in LIBCMT.lib(_file.obj).    X\MSVCRT.lib(MSVCR110.dll)  X
Error   10  error LNK2005: _strtoul already defined in LIBCMT.lib(strtol.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   11  error LNK2005: _memmove already defined in LIBCMT.lib(memmove.obj). X\MSVCRT.lib(MSVCR110.dll)  X
Error   12  error LNK2005: _tolower already defined in LIBCMT.lib(tolower.obj). X\MSVCRT.lib(MSVCR110.dll)  X
Error   13  error LNK2005: _atoi already defined in LIBCMT.lib(atox.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   14  error LNK2005: _isxdigit already defined in LIBCMT.lib(_ctype.obj). X\MSVCRT.lib(MSVCR110.dll)  X
Error   15  error LNK2005: _isdigit already defined in LIBCMT.lib(_ctype.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   16  error LNK2005: _isspace already defined in LIBCMT.lib(_ctype.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   17  error LNK2005: __strtoi64 already defined in LIBCMT.lib(strtoq.obj).    X\MSVCRT.lib(MSVCR110.dll)  X
Error   18  error LNK2005: _memchr already defined in LIBCMT.lib(memchr.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   19  error LNK2005: _fclose already defined in LIBCMT.lib(fclose.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   20  error LNK2005: _strtol already defined in LIBCMT.lib(strtol.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   21  error LNK2005: _sprintf already defined in LIBCMT.lib(sprintf.obj). X\MSVCRT.lib(MSVCR110.dll)  X
Error   22  error LNK2005: _fflush already defined in LIBCMT.lib(fflush.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   23  error LNK2005: __errno already defined in LIBCMT.lib(dosmap.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   24  error LNK2005: __lseeki64 already defined in LIBCMT.lib(lseeki64.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   25  error LNK2005: _getenv already defined in LIBCMT.lib(getenv.obj).   X\MSVCRT.lib(MSVCR110.dll)  X
Error   26  error LNK2005: _isalnum already defined in LIBCMT.lib(_ctype.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   27  error LNK2005: _isalpha already defined in LIBCMT.lib(_ctype.obj).  X\MSVCRT.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).  X\MSVCRT.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).    X\MSVCRT.lib(ti_inst.obj)   X
Error   30  error LNK2005: __strdup already defined in LIBCMT.lib(strdup.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   31  error LNK2005: __close already defined in LIBCMT.lib(close.obj).    X\MSVCRT.lib(MSVCR110.dll)  X
Error   32  error LNK2005: __fileno already defined in LIBCMT.lib(fileno.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   33  error LNK2005: __read already defined in LIBCMT.lib(read.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   34  error LNK2005: __strnicmp already defined in LIBCMT.lib(strnicmp.obj).  X\MSVCRT.lib(MSVCR110.dll)  X
Error   35  error LNK1169: One or more multiply defined symbols found in.   X\..\Release\X.exe  X

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

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

如何解决?

我在 Microsoft Visual Studio 2012 中使用这个 libcurl。 http://curl.haxx.se/download/libcurl-7.19.3-win32-ssl-msvc.zip

【问题讨论】:

  • @SHR:我在几秒钟前添加了错误。最后我尝试使用命名空间,但同样的错误。
  • @AdrianoRepetti:不起作用。我更新了上面 app.cpp 的代码。
  • 如果您没有在预处理器中定义CURL_STATICLIB,请尝试在#include &lt;curl.h&gt; 之前定义。
  • 谢谢@SHR。但现在我还有其他错误。我试图注释掉一些#pragma 注释,但没有任何变化。 (除了更多/不同的错误)

标签: c++ visual-c++ static-libraries libcurl static-linking


【解决方案1】:

这样的问题在 Visual C++ 中很常见,要准确描述如何解决这些问题并不容易。您需要非常小心并真正了解您所包含的库,并且这里没有足够的信息来解决它。

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

我不建议使用#pragmas 来包含链接库。将它们放在 makefile 中,以便您可以在一个地方查看所有内容。

通常,在启用日志记录的情况下运行链接器以准确查看正在调用哪些库会有所帮助。

您的目录树和设置帮助不大,但一个包含 makefile 的最小完整项目可能允许这里的人诊断问题。

【讨论】:

  • 这样的项目有类似 jsfiddle 的东西吗?还是我应该为您上传项目作为 zip 文件?
  • 没有。我们正在谈论的是stackoverflow.com/help/mcve。新项目,可复制的源代码最少,将其全部发布在这里,以便每个人都可以看到和学习​​,并希望得到答案。为您工作更多,为读者带来更多价值。
【解决方案2】:

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

error LNK2005: xxx already defined in MSVCRT.lib(MSVCR100.dll) C:\something\LIBCMT.lib(setlocal.obj)

这里有另一个链接:

LNK2005 errors with LIBCMTD.lib and MSVCRTD.lib

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多