VS编译适用于XP系统sp3的dll全过程-无需vs运行库

时间:2024-03-26 21:15:34

问题1:dll是否依赖于其他的库

答:dll依赖于libcurl+openssl+boost,因此dll要编译成支持xp的静态MFC+MT版,libcurl+openssl+boost同样也要编译成支持XP的release MT版本。

问题2:编译的dll在xp系统出现的normaliz.dll无效映射问题

解决方法:

1、按照网络上找到的方式各种编译libcurl,还是出现normaliz.dll的无效映射问题,最后灵光一现,看到之前

在编译dll的属性中C/C++的预处理中同时加入了BUILDING_LIBCURL和CURL_STATICLIB

解决办法:去掉BUILDING_LIBCURL,只留CURL_STATICLIB和HTTP_ONLY

问题3:完整的libcurl编译过程记录

解决方法:

1、下载libcurl-7.58.0

2、打开curl-7.58.0下的lib\config-win32.h,添加如下代码,用于支持xp系统

#ifdef _WIN32_WINNT
  #undef  _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501
#ifndef WINVER
  #define WINVER 0x0501
#endif

3、替换lib\idn_win32.c中的全部源码如下所示,此解决办法是参照http://www.cnblogs.com/passedbylove/p/5979927.html

/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/

 /*
  * IDN conversions using Windows kernel32 and normaliz libraries.
  */

#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
//#  if defined(_SAL_VERSION)
typedef int (*fnIdnToAscii)(DWORD,const WCHAR *,int,WCHAR *,int);
typedef int (*fnIdnToUnicode)(DWORD,const WCHAR *,int,WCHAR *, int);
//#  endif
#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 /* USE_WIN32_IDN */

4、修改winbuild目录下的MakefileBuild.vc

将63行的CFLAGS替换成64行的CFLAGS,或直接#注释掉,如下

VS2015编译适用于XP系统sp3的dll全过程-无需vs2015运行库

将97、98行注释掉,加入99、100

VS2015编译适用于XP系统sp3的dll全过程-无需vs2015运行库

3、打开VS2015 x86 本机工具命令提示符,cd到\curl-7.58.0\winbuild目录下,执行如下命令,开始编译MT版的libcurl

nmake /f Makefile.vc mode=static VC=14 RTLIBCFG=static

4、完成编译后libcurl的静态库会出现builds目录下的libcurl-vc14-x86-release-static-ipv6-sspi-winssl文件夹中,里面包含我们需要的include头文件和libcurl_a.lib。

5、按照正常的添加头文件和lib的方式加入到所需要的dll中。

问题4:编译openssl+MT版

1、安装AcitivePerl,下载openssl 1.0.1s版

2、打开openssl文件夹中ms\nt.mak文件 
修改为 CFLAG= /MT,若已经是MT可忽略

3、打开VS2015 x86 本机工具命令提示符,cd到openssl根目录下,依次执行如下命令,开始编译MT版的openssl

perl Configure VC-WIN32 ms\do_ms.bat

nmake -f ms/nt.mak

4、编译成功后,可在out32文件夹下找到所需要的lib文件:libeay32.lib,ssleay32.lib;所需要的include文件在in32中。

问题5、在vs2015引用openssl+libcurl时会报

“链接器工具错误 LNK2026 XXX模块对于 SAFESEH 映像是不安全的”

解决方法: 
1.打开该项目的“属性页”对话框。 
2.单击“链接器”文件夹。 
3.单击“命令行”属性页。 
4.将 /SAFESEH:NO 键入“附加选项”框中,然后点击应用。

问题6、EVP_MD_CTX* mdctx = EVP_MD_CTX_new();出错 EVP_MD_CTX_new();未定义

解决方法:修改为,原因是openssl1.0.1版本还尚未将create定义为new,这一版是1.1.0开始的

EVP_MD_CTX* mdctx = EVP_MD_CTX_create();

问题7、vs2015下dll项目设置为可脱离运行库的xp版本

解决方法:

1、右击项目属性:修改为如下红框中的选项,脱离运行环境

VS2015编译适用于XP系统sp3的dll全过程-无需vs2015运行库

2、 运行库选择MTVS2015编译适用于XP系统sp3的dll全过程-无需vs2015运行库

3、链接库-附加依赖项加入:nafxcw.lib、libcmt.lib,顺序不可变,不然会出现重复定义的事情,并在忽略特定默认库中也加入nafxcw.lib;libcmt.lib

4、将最低版本设为5.01VS2015编译适用于XP系统sp3的dll全过程-无需vs2015运行库

 5、命令行中加入

/SUBSYSTEM:CONSOLE,"5.01" /SUBSYSTEM:WINDOWS,"5.01" /SAFESEH:NO 

6、点击应用和确认,完成属性设置

7、为以防万一,在dll的头文件中加入如下代码,支持xp系统

#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501