移植版本 libuv:https://github.com/liigo/libuv-vc6 (支持VC6和XP。作者Liigo)。

我从一年前(大概2013年6,7月份)開始在业余时间做这项移植工作,走走停停,陆续用了一两个月的时间。才基本完毕。这期间做了具体的移植记录。如今公布出来,希望对某些人实用。就在昨天(2014年7月12日)。我又把移植的代码同步到最新的libuv(https://github.com/joyent/libuv)并公布到Github上;可是之前的移植记录没有变更,也许在一定程度上已经部分失效了。

我(Liigo)当初做这项移植工作的原始意图。是打算做一个封装 libuv 的易语言支持库。然而终究还没有做。

理由是没有时间呢,缺乏需求呢,还是懒呢?我临时不想下结论。

此移植版 libuv-vc6 的完整性和准确性尚未得到证明。

可是我的tinyweb 已经基于该移植版编译,而且在Windows XP系统下运作正常。我想这能证明至少它是“基本可用”的。


VC6系统文件 MSWSOCK.H 编译时报错,说不认识“SOCKET”类型:

解决的方法,在前面添加 typedef unsigned int  SOCKET;





uv-win.h 报错说 SRWLOCK 没有定义,解决的方法是在前面添加:

//http://blog.csdn.net/xiewneqi/article/details/4787156

typedef struct SRWLOCK {

void* ptr;

} SRWLOCK, *PSRWLOCK;







uv.h 没有定义 sockaddr_storage,解决的方法是在前面添加:

//http://stackoverflow.com/questions/1345109/why-sockaddr-storage-structure-defined-as-the-way-it-is-defined

struct sockaddr_storage {

short   ss_family;

char    __ss_pad1[6];

int64_t __ss_align;

char    __ss_pad2[112];

};





uv.h 报错说标识符 LPFN_CONNECTEX 语法错误。解决的方法:

将 uv-win.h 内全部 " PASCAL (*" 替换为 " (PASCAL *" 。

把 LPFN_CONNECTEX 的定义从 uv-win.h 拷贝到 uv.h 报错行之前。

uv\src\winapi.h '_REPARSE_DATA_BUFFER'重定义,解决的方法:删除定义,或凝视掉/*defined(_MSC_VER) ||*/

ULONG_PTR 没有定义,增加 typedef unsigned int* ULONG_PTR;





uv\src\winapi.h 没有定义LPOVERLAPPED_ENTRY?增加下面代码:

typedef struct _OVERLAPPED_ENTRY {

  ULONG_PTR    lpCompletionKey;

  LPOVERLAPPED lpOverlapped;

  ULONG_PTR    Internal;

  DWORD        dwNumberOfBytesTransferred;

} OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;





缺少文件iptypes.h? 在以下链接下载后放到uv\src\win

http://stuff.mit.edu/afs/athena/astaff/project/opssrc/nmap-2.54BETA34/mswin32/IPTypes.h





ERROR_INVALID_REPARSE_DATA没有定义?改动为 0x00001128/*ERROR_INVALID_REPARSE_DATA*/





INVALID_FILE_ATTRIBUTES没有定义?改动为 (DWORD)-1/*INVALID_FILE_ATTRIBUTES*/





'bad suffix on number'?把数值后面的ULL删除就可以(10000000ULL -> 10000000)





EAI_BADFLAGS等EAI_*没有定义?增加下面代码:

/* Error codes from getaddrinfo() */

#define EAI_AGAIN           WSATRY_AGAIN

#define EAI_BADFLAGS        WSAEINVAL

#define EAI_FAIL            WSANO_RECOVERY

#define EAI_FAMILY          WSAEAFNOSUPPORT

#define EAI_MEMORY          WSA_NOT_ENOUGH_MEMORY

#define EAI_NOSECURENAME    WSA_SECURE_HOST_NOT_FOUND

//#define EAI_NODATA        WSANO_DATA

#define EAI_NONAME          WSAHOST_NOT_FOUND

#define EAI_SERVICE         WSATYPE_NOT_FOUND

#define EAI_SOCKTYPE        WSAESOCKTNOSUPPORT

#define EAI_IPSECPOLICY     WSA_IPSEC_NAME_POLICY_ERROR





addrinfo/addrinfoW没有定义?在uv.h前面增加下面代码:

//http://msdn.microsoft.com/en-us/library/windows/desktop/ms737530(v=vs.85).aspx

typedef struct addrinfo {

  int             ai_flags;

  int             ai_family;

  int             ai_socktype;

  int             ai_protocol;

  size_t          ai_addrlen;

  char            *ai_canonname;

  struct sockaddr  *ai_addr;

  struct addrinfo  *ai_next;

} ADDRINFOA, *PADDRINFOA;

//http://msdn.microsoft.com/en-us/library/windows/desktop/ms737529(v=vs.85).aspx

typedef struct addrinfoW {

  int              ai_flags;

  int              ai_family;

  int              ai_socktype;

  int              ai_protocol;

  size_t           ai_addrlen;

  PWSTR            ai_canonname;

  struct sockaddr  *ai_addr;

  struct addrinfoW  *ai_next;

} ADDRINFOW, *PADDRINFOW;





WT_EXECUTELONGFUNCTION没有定义?替换为 0x00000010/*WT_EXECUTELONGFUNCTION*/

WT_EXECUTEONLYONCE没有定义?替换为 0x00000008/*WT_EXECUTEONLYONCE*/





in6_addr没有定义?在错误提示行前增加下面代码:

struct in6_addr {

  u_char  s6_addr[16];

};





FILE_FLAG_FIRST_PIPE_INSTANCE没有定义?替换为 0x00080000/*FILE_FLAG_FIRST_PIPE_INSTANCE*/





JOBOBJECT_EXTENDED_LIMIT_INFORMATION没有定义?在前面增加下面代码:

typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION {

  JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;

  IO_COUNTERS                       IoInfo;

  SIZE_T                            ProcessMemoryLimit;

  SIZE_T                            JobMemoryLimit;

  SIZE_T                            PeakProcessMemoryUsed;

  SIZE_T                            PeakJobMemoryUsed;

} JOBOBJECT_EXTENDED_LIMIT_INFORMATION, *PJOBOBJECT_EXTENDED_LIMIT_INFORMATION;





IO_COUNTERS没有定义?在前面增加下面代码:

typedef struct _IO_COUNTERS {

  ULONGLONG ReadOperationCount;

  ULONGLONG WriteOperationCount;

  ULONGLONG OtherOperationCount;

  ULONGLONG ReadTransferCount;

  ULONGLONG WriteTransferCount;

  ULONGLONG OtherTransferCount;

} IO_COUNTERS, *PIO_COUNTERS;





JOB_OBJECT_LIMIT_BREAKAWAY_OK等没有定义?在前面增加下面代码:

#define JOB_OBJECT_LIMIT_SCHEDULING_CLASS       0x80

#define JOB_OBJECT_LIMIT_PROCESS_MEMORY         0x100

#define JOB_OBJECT_LIMIT_JOB_MEMORY             0x200

#define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x400

#define JOB_OBJECT_LIMIT_BREAKAWAY_OK           0x800

#define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK    0x1000

#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE      0x2000





NOINLINE未被识别?替换为 /*NOINLINE*/





((ULONG_PTR) req->event_handle | 1) 语法错误? 改为 ((DWORD) req->event_handle | 1)





IPPROTO_IPV6没有定义?替换为 41/*IPPROTO_IPV6*/





IPV6_MULTICAST_HOPS没有定义?替换为 10/*IPV6_MULTICAST_HOPS*/

IPV6_MULTICAST_LOOP没有定义?替换为 11/*IPV6_MULTICAST_LOOP*/





WSAID_CONNECTEX没有定义?替换为 {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}/*WSAID_CONNECTEX*/





JobObjectExtendedLimitInformation没有定义?替换为 9/*JobObjectExtendedLimitInformation*/





UnregisterWait,UnregisterWaitEx,RegisterWaitForSingleObject等没有定义?在winapi.h中增加下面代码:

typedef BOOL (WINAPI* sUnregisterWait) (HANDLE WaitHandle);

typedef BOOL (WINAPI* sUnregisterWaitEx) (HANDLE WaitHandle, HANDLE CompletionEvent);

typedef VOID (CALLBACK* WAITORTIMERCALLBACK) (PVOID lpParameter, BOOLEAN TimerOrWaitFired);

typedef BOOL (WINAPI* sRegisterWaitForSingleObject)

             (PHANDLE phNewWaitObject,

              HANDLE hObject,

              WAITORTIMERCALLBACK Callback,

              PVOID Context,

              ULONG dwMilliseconds,

              ULONG dwFlags);

然后在winapi.h/.c中參考原有代码补充必需的代码(定义函数指针变量、对其赋值等),然后把对UnregisterWait的调用改为pUnregisterWait(其它类推)。

对于其它在链接时找不到符号的Windows API函数,一并做如上处理。

对于GetProcessMemoryInfo函数要做特殊处理。在两个系统DLL去找事实上现函数地址:

-----------------------------------------------------

  //http://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx

  pGetProcessMemoryInfo = (sGetProcessMemoryInfo)

    GetProcAddress(kernel32_module, "GetProcessMemoryInfo");

  if(pGetProcessMemoryInfo == NULL) {

    pGetProcessMemoryInfo = (sGetProcessMemoryInfo)

      GetProcAddress(GetModuleHandleA("Psapi.dll"), "GetProcessMemoryInfo");

  }

-----------------------------------------------------





找不到IPHlpApi.h?在这里下载:

https://docs.google.com/file/d/0B-VpknkVIm1fdnNabE1ScmlLazQ/edit?usp=sharing

为防止“反复定义IN6_ADDR”的编译错误,须要在 #include "Iphlpapi/iphlpapi.h" 之前先 #define s6_addr 。





找不到psapi.h?在这里下载:

https://docs.google.com/file/d/0B-VpknkVIm1fU3pDRTBDM3JXOWM/edit?usp=sharing





GlobalMemoryStatusEx没有定义?在winapi.h增加下面代码:

typedef struct _MEMORYSTATUSEX {

  DWORD     dwLength;

  DWORD     dwMemoryLoad;

  DWORDLONG ullTotalPhys;

  DWORDLONG ullAvailPhys;

  DWORDLONG ullTotalPageFile;

  DWORDLONG ullAvailPageFile;

  DWORDLONG ullTotalVirtual;

  DWORDLONG ullAvailVirtual;

  DWORDLONG ullAvailExtendedVirtual;

} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;

typedef BOOL (WINAPI* sGlobalMemoryStatusEx) (LPMEMORYSTATUSEX lpBuffer);

然后在winapi.h/.c中參考原有代码补充必需的代码(定义函数指针变量、对其赋值等),然后把对GlobalMemoryStatusEx的调用改为pGlobalMemoryStatusEx。





IP_ADAPTER_UNICAST_ADDRESS_XP没有定义?替换为IP_ADAPTER_UNICAST_ADDRESS,然后

#include "Iphlpapi/iptypes.h" (来源见上文)

由于该头文件里定义的IP_ADAPTER_UNICAST_ADDRESS实质上就是IP_ADAPTER_UNICAST_ADDRESS_XP。





wmemcmp没有定义?把原代码 wmemcmp(data_block->Signature, L"PERF", 4) 改动为:

memcmp(data_block->Signature, L"PERF", 4 * sizeof(TCHAR))





IF_TYPE_SOFTWARE_LOOPBACK没有定义?替换为 24/*IF_TYPE_SOFTWARE_LOOPBACK*/





'sin6_scope_id' : is not a member of 'sockaddr_in6'?

凝视掉 uv-win.h 内的宏定义 UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS。

或者增加以下的定义:

/* The ws2tcpip.h header included in VC6 doesn't define the

 * sin6_scope_id member of sockaddr_in6.  We define our own

 * version and redefine sockaddr_in6 to point to this one.

 */

struct liigo_sockaddr_in6 {

  short sin6_family;

  u_short sin6_port;

  u_long sin6_flowinfo;

  struct in6_addr sin6_addr;

  u_long sin6_scope_id;

};

#define sockaddr_in6 liigo_sockaddr_in6





调用swprintf參数过多?swprintf(path2, len + 3, fmt, pathw)改为swprintf(path2, fmt, pathw)





_set_invalid_parameter_handler是VC2005才增加到CRT函数,VC6里面没有。

在libuv源码里面直接凝视掉对该函数的调用就可以。





_BitScanReverse没有定义?在前面增加下面代码,然后删除VC下对_BitScanReverse的调用,统一用GCC版代码就可以:

//http://stackoverflow.com/questions/355967/how-to-use-msvc-intrinsics-to-get-the-equivalent-of-this-gcc-code

#ifndef __GNUC__

static unsigned int __declspec(inline) popcnt( unsigned int x )

{

    x -= ((x >> 1) & 0x55555555);

    x = (((x >> 2) & 0x33333333) + (x & 0x33333333));

    x = (((x >> 4) + x) & 0x0f0f0f0f);

    x += (x >> 8);

    x += (x >> 16);

    return x & 0x0000003f;

}

static unsigned int __declspec(inline) __builtin_clz( unsigned int x )

{

    x |= (x >> 1);

    x |= (x >> 2);

    x |= (x >> 4);

    x |= (x >> 8);

    x |= (x >> 16);

    return 32 - popcnt(x);

}

static unsigned int __declspec(inline) __builtin_ctz( unsigned int x )

{

    return popcnt((x & -x) - 1);

}

#endif

另外一个模拟实现_BitScanReverse的思路也是可行的:http://bbs.csdn.net/topics/350202744





_InterlockedOr8没有定义?又一次实现uv__atomic_exchange_set例如以下:

static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {

  //return _InterlockedOr8(target, 1);

  __asm mov ecx, target

  __asm mov al, byte ptr [ecx]

  __asm lock or byte ptr [ecx], 1

}





_aligned_malloc, _aligned_free, 等函数没有定义?自己实现这两个函数,代码例如以下:

static void* _aligned_malloc(unsigned int size, unsigned int align) {

  unsigned int rem;

  unsigned char *op, *np;

  op = (unsigned char*) malloc(size + align);

  if(op == NULL) return NULL;

  rem = (unsigned int)op % align;

  np = op + align - rem;

  *(np-1) = (unsigned char)align - rem;

  return np;

}

static void _aligned_free(void* p) {

  if(p) {

    unsigned char n = *((unsigned char*)p - 1);

    free((unsigned char*)p - n);

  }

}





InterlockedCompareExchangePointer在新版VC中是编译器生成的函数。并不存在于kernel.dll里面,而VC6显然不可能生成该函数。解决的方法:

pInterlockedCompareExchangePointer = (sInterlockedCompareExchangePointer) GetProcAddress(kernel32_module, "InterlockedCompareExchange");

//VC6 always create x86 programs. 由于VC6总是生成32位程序。不可能调用64位版的函数。





缺少常量IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP?在前面增加例如以下代码:

#ifndef IPPROTO_IPV6

#define IPPROTO_IPV6 41

#endif





#ifndef IPV6_MULTICAST_IF

#define IPV6_MULTICAST_IF 9

#endif

#ifndef IPV6_ADD_MEMBERSHIP

#define IPV6_ADD_MEMBERSHIP 12

#endif

#ifndef IPV6_DROP_MEMBERSHIP

#define IPV6_DROP_MEMBERSHIP 13

#endif





常量ERROR_INVALID_REPARSE_DATA没定义?改成以下这样:

4392/*ERROR_INVALID_REPARSE_DATA*/

版权声明:这篇文章的博客Liigo原版的,不得擅自转载。

移植 libuv 至 Visual C++ 6.0 并支持 Windows XP 编译系统的更多相关文章

  1. Centos7.3下安装Jumpserver 1.0.0(支持windows组件)

    Jumpserver最新版本支持windows组件,废话不多介绍了,下面直接介绍下部署过程: 0)系统环境 CentOS 7.3 IP: 192.168.10.210 [root@jumpserver ...

  2. Centos7.4下安装Jumpserver 1.0.0(支持windows组件)

    0)系统环境CentOS 7.4 IP: 192.168.100.10 [root@jumpserver-server ~]# cat /etc/redhat-release CentOS Linux ...

  3. 微软Visual Studio Code 0.8.0发布,新增多种主题

    月30日,Build 开发者大会上,正式宣布了 Visual Studio Code 项目;并将其定义为:一个运行于 Mac OS X.Windows和 Linux 之上的,针对于编写现代 Web 和 ...

  4. Microsoft Visual SourceSafe 6.0 无法关联项目

    最近遇到Microsoft Visual SourceSafe 6.0 安装好以后, 无法关联项目,导致无法进行版本控制,研究以后,发现需要运行一个程序,在安装目录下 ..\Visual Source ...

  5. Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)

    Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...

  6. 又一次的Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat)

    ~~~~~~~~~~~My problem is here~~~~~~~~~~~~~~~~~~~~~~ Error: Microsoft visual C++ 10.0 is required (un ...

  7. Win7 64下Visual C++ 6.0不兼容

    Win7 64下Visual C++ 6.0不兼容 安装VSE6.0: 1.运行setup.exe安装程序,会弹出如下的的 程序兼容性助手 提示框,这个是Win7在警告用户vc6存在兼容性问题:此程序 ...

  8. Visual C++ 6.0使用教程

    Visual C++它大概可以分成三个主要的部分: 3. Platform SDK.这才是Visual C++和整个Visual Studio的精华和灵魂,虽然我们很少能直接接触到它.大致说来,Pla ...

  9. pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat

    pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat Windows7下pip安装包报错:Microso ...

随机推荐

  1. Lisp: Common Lisp, Racket, Clojure, Emacs Lisp - Hyperpolyglot

    Lisp: Common Lisp, Racket, Clojure, Emacs Lisp - Hyperpolyglot Lisp: Common Lisp, Racket, Clojure, E ...

  2. win32收不到F10按键消息解决办法

    在WM_KEYDOWN中处理F10(VK_F10)消息总是获取不到,后来用spy++监听窗口消息发现按下F10并没有WM_KEYDOWN消息产生,而是产生了WM_SYSKEYDOWN http://b ...

  3. WebBrowser控件禁用超链接转向、脚本错误提示、默认右键菜单和快捷键

    原文:WebBrowser控件禁用超链接转向.脚本错误提示.默认右键菜单和快捷键 WebBrowser控件禁用超链接转向.脚本错误提示.默认右键菜单和快捷键从 VS2005开始,VS自带的 WebBr ...

  4. Leetcode-Database-176-Second Highest Salary-Easy(转)

    leetcode地址:https://oj.leetcode.com/problems/second-highest-salary/ 这个问题很有趣,是要求我们写个sql来查询Employee表里第二 ...

  5. 解决Ubuntu下安装VMware错误could not open /dev/vmmon

    在安装VMware并启动新建的虚拟系统时,会出现错误could not open /dev/vmmon. 普通情况下,这是因为ubuntu系统gcc版本号的问题.我机器上是gcc-4.5,于是我将其改 ...

  6. 应届GIS硕士求职经验总结

    记录一下作为一个GIS应届毕业生在帝都找工作的历程吧,之后的经历可能丰富多彩,可能萎靡不振,但这一次走过来了就是这一次的.希望以史为鉴,各位客官也能有所收获. 定位 我们这一届的"烟酒生&q ...

  7. loj1341(数学)

    传送门:Aladdin and the Flying Carpet 题意: 给出两个正整数1<=m<=n<=1e12.问N可以拆成多少对p*q,使得p和q中最小的不小于a,且p!=q ...

  8. jquery在元素上收购事件

    jquery的给元素绑定的事件能够用data方法取出来 通过$(element).data("events")来获取 // 比方给一个button绑定两个click事件 $(&qu ...

  9. Android中怎样在应用A中启动或安装应用B

    看到别人做的游戏攻略,想着自己的游戏攻略也加入新的功能,即Android中怎样在应用A中启动或安装应用B.就查了一些资料整理下来. 启动或安装对应的应用的方法: Step1:推断是否安装目标应用.仅仅 ...

  10. 组队赛第二场:字符串哈希+DP

    长春现场赛 HDU 4821  思路:这题周赛的时候没做出来,有点可惜了.要是当时记起来unsigned long long自己主动取模,然后提醒一下大帝的话,后续大帝就能过了. 唉,导致让他取了好多 ...