移植版本 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. HealthKit开发教程Swift版:起步

    原文:HealthKit Tutorial with Swift: Getting Started 作者:Ernesto García 译者:Mr_cyz ) HealthKit是iOS 8中的新的A ...

  2. 14.4.3.3 Making the Buffer Pool Scan Resistant

    14.4.3.3 Making the Buffer Pool Scan Resistant 让Buffer Pool 扫描 相比使用一个严格的LRU算法, InnoDB 使用一个技术来最小化数据的总 ...

  3. 高效 Java Web 开发框架 JessMA v3.2.3 beta-1 发布

    JessMA(原名:Portal-Basic)是一套功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hib ...

  4. 《转》Linux下的多线程编程

    原地址:http://linux.chinaunix.net/doc/program/2001-08-11/642.shtml 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程 ...

  5. JAVA - 优雅的记录日志(log4j实战篇) (转)

    写在前面 项目开发中,记录错误日志有以下好处: 方便调试 便于发现系统运行过程中的错误 存储业务数据,便于后期分析 在java中,记录日志有很多种方式: 自己实现 自己写类,将日志数据,以io操作方式 ...

  6. A Game of Thrones(17) - Bran

    It seemed as though he had been falling for years. Fly, a voice whispered in the darkness, but Bran ...

  7. adnroid仿miui的dialog

    先来看下效果图: 当中show和dismiss的时候有动画效果. 原先试过使用PopupWindow来做,可是使用的时候不是那么舒服,毕竟不是dialog嘛. 所以这次尝试还是使用dialog来做 , ...

  8. bzoj2301(莫比乌斯反演+分块)

    传送门:2301: [HAOI2011]Problem b 题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y ...

  9. Application to find the maximum temperature in the weather dataset

    import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop. ...

  10. poj1185(状压dp)

    题目连接:http://poj.org/problem?id=1185 题意:给出一张n*m的地图,'H'表示高地,不能部署炮兵,'P'表示平原,可以部署炮兵,炮兵之间必须保持横向.纵向至少2个格子的 ...