CURL/libcurl编译,32位,兼容XP系统,静态库,解决找不到入口,normaliz.dll包缺失问题

此文章均摘抄自其他大佬的文章,结合我自身遇到的问题,进行的整合

步骤

        1、下载curlcurl/libcurl

        2、修改MakefileBuild.vc

        3、修改idn_win32.c

        4、nmake编译

        5、配置项目

        6、测试

 下载CURL/libcurl

下载地址:https://curl.se/download.html

其他版本:https://curl.se/download/

根据项目配置选择合适的curl版本。

据不完全了解目前兼容XP系统的最高版本为curl-7.56.1,如需支持XP请下载此以下版本

以下均以curl-7.56.1为例。

修改MakefileBuild.vc

为解决XP兼容性问题,编辑curl-7.56.1\winbuild\MakefileBuild.vc文件,加入下面的红色字体

CFGSET=FALSE
WINBUILD_DIR=`cd`
ZIP        = zip.exe

# Allow changing C compiler via environment variable CC (default cl.exe)
# This command macro is not set by default: https://msdn.microsoft.com/en-us/library/ms933742.aspx
!If "$(CC)" == ""
CC = cl.exe
!Endif

!IF "$(VC)"=="6"
CC_NODEBUG  = $(CC) /O2 /DNDEBUG
CC_DEBUG    = $(CC) /Od /Gm /Zi /D_DEBUG /GZ
CFLAGS      = /I. /I../lib /I../include /nologo /W4 /wd4127 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
!ELSE
CC_NODEBUG  = $(CC) /O2 /DNDEBUG
CC_DEBUG    = $(CC) /Od /D_DEBUG /RTC1 /Z7 /LDd
CFLAGS      = /I. /I ../lib /I../include /nologo /W4 /wd4127 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL /D_USING_V110_SDK71_
!ENDIF

LFLAGS     = /nologo /machine:$(MACHINE)
LNKDLL     = link.exe /DLL
LNKLIB     = link.exe /lib

CFLAGS_PDB = /Zi
LFLAGS_PDB = /incremental:no /opt:ref,icf

CFLAGS_LIBCURL_STATIC  = /DCURL_STATICLIB

WIN_LIBS    = ws2_32.lib wldap32.lib advapi32.lib

BASE_NAME              = libcurl
BASE_NAME_DEBUG        = $(BASE_NAME)_debug
BASE_NAME_STATIC       = $(BASE_NAME)_a
BASE_NAME_STATIC_DEBUG = $(BASE_NAME_STATIC)_debug

LIB_NAME_STATIC        = $(BASE_NAME_STATIC).lib
LIB_NAME_STATIC_DEBUG  = $(BASE_NAME_STATIC_DEBUG).lib
LIB_NAME_DLL           = $(BASE_NAME).dll
LIB_NAME_IMP           = $(BASE_NAME).lib
LIB_NAME_DLL_DEBUG     = $(BASE_NAME_DEBUG).dll
LIB_NAME_IMP_DEBUG     = $(BASE_NAME_DEBUG).lib

PDB_NAME_STATIC        = $(BASE_NAME_STATIC).pdb
PDB_NAME_STATIC_DEBUG  = $(BASE_NAME_STATIC_DEBUG).pdb
PDB_NAME_DLL           = $(BASE_NAME).pdb
PDB_NAME_DLL_DEBUG     = $(BASE_NAME_DEBUG).pdb

# CURL Command section
PROGRAM_NAME = curl.exe
CURL_CFLAGS   =  /I../lib /I../include /nologo /W4 /EHsc /DWIN32 /FD /c /D_USING_V110_SDK71_
CURL_LFLAGS   = /nologo /out:$(DIRDIST)\bin\$(PROGRAM_NAME) /subsystem:console,"5.01" /machine:$(MACHINE)
CURL_RESFLAGS = /i../include

引用自CSDN大神:weixin_38169886

https://blog.csdn.net/weixin_38169886/article/details/99773426

修改idn_win32.c

为解决运行时出现缺失normaliz.dll问题,部分XP系统不包含normaliz.dll库

修改curl-7.56.1\lib\idn_win32.c文件,WANT_IDN_PROTOTYPES里修改为两个函数指针,对curl_win32_idn_to_ascii和curl_win32_ascii_to_idn两个函数进行修改。

#include "curl_setup.h"

#ifdef USE_WIN32_IDN

#include "curl_multibyte.h"
#include "curl_memory.h"
#include "warnless.h"

  /* The last #include file should be: */
#include "memdebug.h"

#ifdef WANT_IDN_PROTOTYPES
typedef int (*fnIdnToAscii)(DWORD,const WCHAR *,int,WCHAR *,int);
typedef int (*fnIdnToUnicode)(DWORD,const WCHAR *,int,WCHAR *, int);

#endif

#define IDN_MAX_LENGTH 255

bool curl_win32_idn_to_ascii(const char *in, char **out);
bool curl_win32_ascii_to_idn(const char *in, char **out);

bool curl_win32_idn_to_ascii(const char *in, char **out)
{
  bool success = FALSE;

  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
 
  if(in_w) {
    wchar_t punycode[IDN_MAX_LENGTH];
    int chars = -1;
    fnIdnToAscii IdnToAscii;
    HINSTANCE hNormalizDLL = LoadLibrary("normaliz.dll");
    if (!hNormalizDLL) {
        FreeLibrary(hNormalizDLL);
        assert(hNormalizDLL);
        return FALSE;
    }
    IdnToAscii = (fnIdnToAscii)GetProcAddress(hNormalizDLL, "IdnToAscii");
    if (!IdnToAscii) {
        assert(IdnToAscii);
        return TRUE;
    }
    chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
    
    free(IdnToAscii);
    FreeLibrary(hNormalizDLL);

    free(in_w);
    if(chars) {
      *out = Curl_convert_wchar_to_UTF8(punycode);
      if(*out)
        success = TRUE;
    }
  }

  return success;
}

bool curl_win32_ascii_to_idn(const char *in, char **out)
{
  bool success = FALSE;

  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
  if(in_w) {
    size_t in_len = wcslen(in_w) + 1;
    wchar_t unicode[IDN_MAX_LENGTH];
    int chars = -1;
    fnIdnToUnicode IdnToUnicode;
    
    HINSTANCE hNormalizDLL = LoadLibrary("normaliz.dll");
    if (!hNormalizDLL) {
        FreeLibrary(hNormalizDLL);
        assert(hNormalizDLL);
        return FALSE;
    }
    IdnToUnicode = (fnIdnToUnicode)GetProcAddress(hNormalizDLL, "IdnToUnicode");
    if (!IdnToUnicode) {
        assert(IdnToUnicode);
        return FALSE;
    }
    chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len),
                             unicode, IDN_MAX_LENGTH);
    
    free(IdnToUnicode);
    FreeLibrary(hNormalizDLL);
    free(in_w);
    if(chars) {
      *out = Curl_convert_wchar_to_UTF8(unicode);
      if(*out)
        success = TRUE;
    }
  }

  return success;
}

#endif

引用自51CTO博客大神:passedbylove

https://blog.51cto.com/u_296714/5588761

nmake编译

打开开始菜单

直接以管理身份运行②,或者选择①,然后选择以下工具,以管理员身份运行

cd进入winbuild文件夹下

输入以下命令,编译curl(有大神说执行前需先运行一下curl-7.56.1\buildconf.bat文件)

nmake /f Makefile.vc mode=static VS=12 RTLIBCFG=static MACHINE=x86 DEBUG=yes ENABLE_IDN=no

mode=static 目标文件为静态库

VS=12 VC的版本 我用的VS2013对应的版本号是12,需要改为所用编辑器对应的VC版本

RTLIBCFG=static 将指定库构建为静态库,默认为动态库

MACHINE=x86 系统位数,我这里需要兼容XP,所以选择X86,兼容32位操作系统

DEBUG=yes 编译配置,根据自身需要选择debug或release,我这里用的是debug

ENABLE_IDN=no libcurl会尝试使用 Windows IDN APIs。然而,在某些情况下,尤其是当目标平台(如 Windows XP)不支持这些 APIs 时,或者当你不希望使用这些 APIs 时,你可能需要将 ENABLE_IDN 设置为 no。

C:\WINDOWS\system32>f:

F:\>cd myclib\curl\curl-7.56.1\winbuild

F:\myclib\curl\curl-7.56.1\winbuild>nmake /f Makefile.vc mode=static VS=12 RTLIBCFG=static MACHINE=x86 DEBUG=yes ENABLE_IDN=no

引用自CSDN大神:LongXiao4

https://blog.csdn.net/LongXiao4/article/details/105840031/

至此,编译成功生成文件

配置项目

修改配置和平台工具集

保持对应

引入include和lib

包含目录对应include目录,库目录对应lib目录,我是把生成的文件放入项目中引用的

添加附加依赖项

添加生成库的名称,也可以在代码中引入库

预处理器定义加入CURL_STATICLIB

运行库选择生成库文件命令中所对应的运行库,我这里选择的是MTD(RTLIBCFG=static对应MT,DEBUG=yes对应Debug,所以选择MTD)

测试

代码编写(很容易搜到,我这里备注比较少,可以看其他文章)

#include <iostream>
#include<Windows.h>
#include<string.h>
#include<stdio.h>

#define BUILDING_LIBCURL
#include "curl/include/curl/curl.h"

static size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata) {
	std::string* response = reinterpret_cast<std::string*>(userdata);
	size_t data_size = size * nmemb;
	response->append(ptr, data_size);
	return data_size;
}
std::string Post(const std::string strUrl, const std::string strPost)
{
	CURLcode res;
	curl_global_init(CURL_GLOBAL_ALL); // 首先全局初始化CURL
	CURL* curl = curl_easy_init();

	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
	curl_easy_setopt(curl, CURLOPT_POST, 1);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
	std::string response;
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
	res = curl_easy_perform(curl);

	// 检查返回值
	if (res == CURLE_OK) {
		std::cout << "Request succeed." << std::endl;
		std::cout << "Response: " << response.c_str() << std::endl;
	}
	else {
		std::cout << "Request failed. Error code: " << res << std::endl;
	}

	curl_easy_cleanup(curl);
	return response;
}
int main()
{
	system("chcp 65001");
	std::string strUrl = "https://baike.baidu.com/api/usercenter/login";
	std::string strPost = "msg=1&t=1721447495404"; 
	Post(strUrl, strPost);

	system("pause");
	return 0;
}

至此结束,感谢各位大神或即将成为大神的人阅读,如遇问题,请联系我(工作忙回复不及时,请见谅)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值