win环境win7 mingw安装 lua 静态库

mingw/vc2008移植问题记录 - weimingtom的待宵草 - ITeye技术网站
博客分类:
注意:以下解决方法不一定适用,仅个人记录备忘
关于VC和gcc的区别,请参考以下链接:
gccとVC(日文)
超初心者のプログラム入門
Problem 1: VC2008 运行时库属性页-&C/C++-&代码生成-&运行时库(一般是MTd和MT)
Problem 2: inline函数重定义问题,可以考虑用#if屏蔽掉#if defined(_MSC_VER) && (_MSC_VER & 1500) //VC 9inline int inet_pton(int af, register const char *cp, struct in_addr *addr)
Problem 3: libevent.lib 依赖问题。如果使用VC2008,并且建立起libevent源代码工程。可以考虑使用“链接器-&输入-&附加依赖项”,这样就不再需要添加libevent.lib
Problem 4: errno赋值问题errno = 0需要改为set_errno(0);原因是vc2008的编译器在多线程时不允许你直接给errno赋值,貌似是为了线程安全,这时候就得写个宏。
#if defined(_MT) || defined(_DLL)
# define set_errno(x)
(*_errno()) = (x)
# define set_errno(x)
errno = (x)
不知道linux怎么处理线程安全(好像linux根本就不需要这么复杂)。
Problem 5:APR导入问题。如果有一天突然想用APR或APU来编程,你就得遇到这种囧问题——不知道怎么在vc2008里链接。一种方法是:宏定义添加APR_DECLARE_EXPORT(补充:或者APU_DECLARE_EXPORT)WIN32确保是动态导出api和动态导入APR DLL
附加依赖项目选择使用动态链接的lib(以防万一把apr和apu的都加上)libapr-1.lib libaprutil-1.lib如果不知道apr为何物,就最好别管这种复杂问题(Apache httpd的代码和API需要高手才看得懂的)推荐用动态库(不会遇到一堆链接错误)如果用静态库要改用另一套lib和APR_DECLARE_STATIC
Problem 6: 函数声明和定义不同。可能vc2008会对类型很敏感。最好改为统一。
Problem 7: snprintf问题Windows SDK没有snprintf这个函数,用_snprintf代替
#ifndef snprintf
#define snprintf _snprintf
Problem 8: strtoll和strtoull问题
#if _MSC_VER & 1300
#define strtoll(p, e, b) ((*(e) = (char*)(p) + (((b) == 10) ? strspn((p), "") : 0)), _atoi64(p))
#define strtoll(p, e, b) _strtoi64(p, e, b)
#ifndef strtoull
#define strtoull strtoul
遇到这种问题需要查SDK的手册,你会发现有个叫_atoi64的API(这个函数很早就有了,用于32位操作系统上,定义在stdlib.h)。当然如果你不喜欢上面代码写得那么复杂,可以一概改为_atoi64。另外,还需要知道有个关键字__int64,可以用它表示有符号和无符号的64位整数(很少出现,除非你要用64位来提高性能)_strtoi64的用法稍微不同。还有个叫_i64toa的API,是_atoi64的逆转换。
补充:可能对于64位整数,还要考虑格式化字符串printf的问题,所以问题远没有这么简单。
Problem 9:符号无定义。比如你用了TransmitFile,你就得加mswsock.lib(不过好像加的顺序有讲究的)如果不知道加什么,就查sdk帮助和搜索,一般微软会很热心地注明这个API需要用那个lib去链接。把所有lib加上去试也可以(只是这种方法有点菜)
Problem 10:MySQL UDF问题比较通用的方法是写个.def文件LIBRARY "xxx"EXPORTS...然后在工程中加入这个def编译好dll后拷贝到C:\Program Files (x86)\MySQL\MySQL Server 5.1\lib\plugin或者根据show variables like "plugin_dir";判断插件位置如果涉及别的dll,需要把依赖dll拷贝到PATH的路径下,例如C:\Program Files (x86)\MySQL\MySQL Server 5.1\bin否则mysqld会因为缺乏dll而启动不了UDF而认为UDF不存在。创建SQL类似于CREATE FUNCTION xxx RETURNS INT SONAME "xxx.dll";安装成功后select name, dl from mysql.查看要调试UDF可以用fprintf(stderr,...)的方法,然后用mysqld --console来启动mysqld。另外最好用debug版测试,万一崩溃了,mysqld会把输出一些堆栈信息到控制台上。
Problem 11: WSAStartup和memset问题
#ifdef WIN32
WSADATA wsaD
if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0) {
fprintf(stderr, "Socket Initialization Error. Program
aborted\n");
这是windows的特有问题(写linux网络程序的人大概会很郁闷),如果有一天发现getaddrinfo返回非零,检查一下main函数有没有加WSAStartup。(连127.0.0.1都解析不了会很可笑)。另外memset也是个需要注意的问题,例如初始化struct addrinfo变量hints需要memset(&hints, 0, sizeof (hints));(有时候你忽略这个问题会出现一些古怪的结果)然后给某个成员变量赋值。linux的写法就不会那么复杂,它用C99的写法,在初始化时直接给变量的成员函数赋初始值。顺便一提VC支持字符串的全0初始,例如char s[10] = {0};比单纯写char s[10];要安全得多。
VC其实可以像gcc那样给结构体对象赋初值,只不过不是写成 type a={.x = 10, };
而是写成type a={a.x = 10,};所以没必要用memset(低版本的VC则有必要?)
problem 12:缺少BSD套接字头文件
在linux网络编程中经常会出现
#include &netinet/tcp.h&#include &arpa/inet.h&
有时还会有
#include &sys/socket.h&
还有其他,如果只是使用BSD套接字,
问题是,mingw没有(VC也是)。
但windows上的确存在BSD套接字API的子集,只不过需要包含的头文件不是上面那些,而是
#include &winsock2.h&
#include &ws2tcpip.h&
如果对这个问题感兴趣,可以参考这些资料:
* memcached1.2.6-win32移植的源代码
*PostgreSQL的源码(\src\include\port\win32),对win32的移植
(注:VC6似乎不行,待考)
problem 13:缺少sys/poll.h
win32没有现成的机制实现poll(轮询),也就是说:poll()不可移植
不过事实上有人给出poll()的非正式实现:
(未经试验,不过好像可以试试看)
* libmemcached
/poll/poll.c
-------------------------
(:补充drizzle,发现它的源代码包中带有poll.c,不知道是否可用)
-------------------------
如果你使用cygwin,这个问题可以忽略(因为默认是有poll.h和poll()的实现)
poll其实可以在msys的SDK中使用
msysDVLPR-1.0.0-alpha-1.tar.gz
但最终生成的exe导入了MSYS-1.0.DLL,而MSYS-1.0.DLL不可以单独使用(依赖于msys)
如果只用于msys控制台,可以尝试用这个SDK(gcc version 2.95.3-1)
安装教程:
注意,它需要与msys目录合并,不是放在/mingw目录下
继续补充:
poll其实有win32的port,参考
不过这个API仅用于Vista以上
problem 14: pthread-w32静态库造成程序崩溃的问题。
由于dll.c中dllmain()调用了这两个API(定义在pthread.h)
PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
如果pthread-w32被静态链接到程序中,需要在main()函数开头调用pthread_win32_process_attach_np初始化,否则程序会崩溃,且很难找到崩溃的原因(即使使用CDT调试)。
(补注:)代码如下:(在main函数最开始的地方执行)
#ifdef __MINGW32__
ptw32_processInitialize();
//ptw32_processTerminate();
problem 15: 关于VC6构造函数的初始化表的问题。
不可以使用带命名空间的基类。
例如class X:public std::Y{}
构造函数X():std::Y(0),...{}是编译出错的,
需要绕圈,用typedef std::Y std_Y,然后再初始化:X():std_Y(0),...{}
problem 16:关于VC6的模板参数和嵌套问题。
有些时候,如果没有用到模板参数,那么template可以省略,
但对于VC6来说,省略template&class T&有时就偏偏不行。
VC6似乎不能把嵌套template成员函数单独写再类定义外部。
例如template&class T& template&class C&...
一种解决办法是,放在类定义内部。
problem 17:VC6在成员函数中调用基类方法可能会编译失败。
原因不明,不过用某些方法绕过这种编译错误,例如使用未被覆盖或重载的方法代替(废话。。。)
problem 18: 使用winsock的API,在VC2008编译时出现大量的错误:
1&c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(91) : warning C4005: “AF_IPX”: 宏重定义1&
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(460) : 参见“AF_IPX”的前一个定义
一般是因为出现这样的包含
#include &windows.h&#include &winsock2.h&
导致一堆宏重定义
使用宏WIN32_LEAN_AND_MEAN可以屏蔽之(应该。。。)
用#define或者VC2008工程的预处理器设置均可。
problem 19: 线程局部变量的区别:
mingw32 does not support __thread (thread local storage).but msvc support like it with _declspec(thread).however mingw32 can ignore that.
problem 20:asprintf和vasprintf
-----------------------
注意,这里有个开源实现(未试验)
-----------------------
出现在lua-checker的代码中
这两个函数VC没有,需要用特殊方法近似地模拟,一种方法是使用vsnprintf(低版本的VC可能没有这个函数)
#ifdef _MSC_VER
#pragma warning(disable:4065)
#pragma warning(disable:4996)
用malloc分配内存,在程序结束后自动回收
/svn-history/r40/trunk/jbig2enc_modified/jbig2.cc
// -----------------------------------------------------------------------------
// Windows, sadly, lacks asprintf
// -----------------------------------------------------------------------------
#include &stdarg.h&
static int asprintf(char **strp, const char *fmt, ...)
va_start(va, fmt);
const int required = vsnprintf(NULL, 0, fmt, va);
char *const buffer = (char *) malloc(required + 1);
const int ret = vsnprintf(buffer, required + 1, fmt, va);
va_end(va);
static int vasprintf(char **strp, const char *fmt, va_list va)
const int required = vsnprintf(NULL, 0, fmt, va);
char *const buffer = (char *) malloc(required + 1);
const int ret = vsnprintf(buffer, required + 1, fmt, va);
另一种做法是使用临时文件:
totem-plparser
实现大概是这样:
#include "config.h"
#include &stdio.h&
#include &stdlib.h&
#include &stdarg.h&
#ifdef _WIN32
#include &windows.h&
int totem_private_asprintf(char **out, const char *fmt, ...)
int ret_status = EOF;
char dir_name[2001];
char file_name[2000];
FILE *fp = NULL;
char *work = NULL;
va_start(ap, fmt);
/* Warning: tmpfile() does not work well on Windows (MinGW)
if user does not have write access on the drive where
working dir is? */
#ifdef _WIN32
/* file_name = G_tempfile(); */
GetTempPath ( 2000, dir_name );
GetTempFileName ( dir_name, "asprintf", 0, file_name );
fp = fopen ( file_name, "w+" );
fp = tmpfile();
#endif /* _WIN32 */
if ( fp ) {
count = vfprintf(fp, fmt, ap);
if (count &= 0) {
work = calloc(count + 1, sizeof(char));
if (work != NULL) {
rewind(fp);
ret_status = fread(work, sizeof(char), count, fp);
if (ret_status != count) {
ret_status = EOF;
free(work);
work = NULL;
fclose(fp);
#ifdef _WIN32
unlink ( file_name );
#endif /* _WIN32 */
va_end(ap);
return ret_
虽然麻烦,但在没有vsnprintf时是个不错的应急方案。
重申一下,这只是近似的方案,并不一定和真正的asprintf功能一样。
problem 21 获取指定文件名(可能是相对路径)的完整目录名
和问题20一样,出现在lua-checker的代码中
我的移植方案是用VC的C运行时库函数_fullpath和_splitpath来模拟dirname:
#ifndef _MSC_VER
#include &libgen.h&
// For dirname()
#include &stdio.h&
#include &conio.h&
#include &stdlib.h&
#include &direct.h&
static const char *dirname(const char *partialPath)
static char full[1000] = {0};
static char path_buffer[1000] = {0};
static char drive[1000] = {0};
static char dir[1000] = {0};
static char fname[1000] = {0};
static char ext[1000] = {0};
static char fulldir[1000] = {0};
if( _fullpath( full, partialPath, sizeof(full) ) != NULL )
_splitpath( full, drive, dir, fname, ext );
strcpy(fulldir, drive);
strcat(fulldir, dir);
strcpy(fulldir, "");
problem 22 只能读文件4KB以内的内容?
使用fopen的"r"模式,一次性读取4KB内容到char[](使用fread函数),发现4KB以外的内容都是0(没有完整地读出)。
正确的做法是使用"rb“模式。
problem 23 VC2008的char类型的无符号问题
因为char在旧版的C中充当BYTE类型来使用(unsigned char),但新版的VC2008实施强类型,char类型将被当作有符号数来处理,如果想把char当作无符号来使用,应该更改VC工程的属性,添加/J参数。
problem 24 long long 输出
#include &stdio.h&
int main(void)
long long mem = ;
printf("mem=%ld\n",mem);
//输出不正确呀,应该用什么转移符?
print("mem=%lld\n",men);
problem 25: 找不到strcasecmp
#ifdef _MSC_VER
#include &string.h&
#define strcasecmp stricmp
#define strncasecmp
problem 26 : 使用SDL头文件时出现undefined reference to `WinMain@16'
原因是SDL.h把main宏定义了,可以用nm或dumpbin检查.o文件的符号是否有_main(可以用grep过滤)
解决办法可以取消main的宏定义:
#undef main
int main( int argc, char* argv[] ) {
补注: 正确做法应该是使用libSDLmain.a的WinMain入口,方法是把链接参数中的-lmingw32提前到-lSDLmain之前,例如
-lmingw32 -lSDLmain -lSDL
problem 27: drand48和srand48
Windows上可以简单地实现
#ifdef _WIN32
#define drand48() (((float) rand())/((float) RAND_MAX))
#define srand48(x) (srand((x)))
注意,对随机数取模是个不好的设计,因为取模得到序列的可能不够均匀。
problem 28: bcb6的“Call to function 'xxx' with no prototype”警告
对于空参数表的函数声明,必须指明为void,例如xxx(void);
(后续,待修改)
problem 29: 在Windows上使用MinGW+SWIG书写JNI
Windows上的JNI实际上是Java虚拟机调用原生dll的导出函数。
尝试使用Cygwin+SWIG生成JNI,但不成功(提示aborted)
但使用mingw则没有问题(可能是cygwin的dll造成JNI不可用)
需要注意的是最后编译dll时使用的参数-Wl,--add-stdcall-alias,见
我尝试用手工Makefile编译JNI,编译工程是官方发布包中的swigwin-2.0.3\Examples\java\simple
方法如下:
1. 创建目录swigtest,把simple示例的代码都复制进去
2. 把jdk下的include文件(我的JDK头文件在
D:\java\jdk1.6.0_20\include
D:\java\jdk1.6.0_20\include\win32
)全部复制到目录swigtest(include\win32下的文件直接和include下的头文件放在一起)
这样做是因为,我在使用-I时无法指向这两个目录(原因不明)
3. 手工书写新的Makefile
(注意,我的javac在d:\java\jdk1.6.0_20\bin\javac.exe,所以指向mingw风格的目录/d/java/jdk1.6.0_20/bin/javac)
RM := rm -f
SWIG := swig
OBJS := example.o example_wrap.o
CFLAGS := -I.
# -I/D/java/jdk1.6.0_20/include -I/D/java/jdk1.6.0_20/include/win32
# -I/cygdrive/d/java/jdk1.6.0_20/include
JAVAC := /d/java/jdk1.6.0_20/bin/javac
all : example.dll java
${JAVAC} *.java
example.dll : ${OBJS}
${CC} -shared ${CFLAGS} -Wl,--add-stdcall-alias -o $@ ${OBJS}
# -mno-cygwin
${CC} ${CFLAGS} -o $@ -c $&
# exampleJNI.java
example_wrap.c : example.i
${SWIG} -o $@ -java $&
${RM} *.o *.class *.dll example.java example_wrap.c exampleJNI.java
然后运行:
& make clean all
& java runme
problem 30 编译动态库和静态库
gcc -shared -o &.dll文件& &.o文件&...
ar rcs &.a文件& &.o文件& ...
(有时下面还可以对.a文件使用ranlib命令,但一般可以忽略不做)
problem 31
configure时输出.i文件检查宏展开后的编译错误
CFLAGS=-save-temps
problem 32
isspace错误
如果在cygwin中使用不经过类型转换的isspace
array subscript has type ‘char’
解决办法如下
/* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */#define xisspace(c) isspace((unsigned char)c)
或者手工转换类型
类似的情况出现在cygwin的大部分isXXX函数
problem 33 printf系输出的乱码问题
C 使用wprintf,_tprintf 打印简体中文的方法 【Locale.h】
需要分两种情况考虑:
1. 非Unicode版
_ftprintf(stderr, _T("%S\n"), "你好吗");
2. Unicode版
#include &locale.h&
setlocale(LC_ALL, "");
_ftprintf(stderr, _T("%s\n"), _T("你好吗"));
注意,两种情况的%s的大小写含义是不一样的!
这一点在微软的文档中有详细说明——
就是说printf的%s是非Unicode字符串的占位符;
而wprintf的%s是Unicode字符串的占位符;
printf的%S是Unicode字符串的占位符;
而wprintf的%S是非Unicode字符串的占位符;
wprintf还需要setlocale才能正常在控制台中输出。
另外,出现乱码还可能是因为——参数个数不匹配
problem 34 VC6与MinGW的内联汇编。
有时需要在C中嵌入汇编以获取底层硬件信息。
例如在mingw中测试CPU频率
static long CPUClock __asm__("CPUClock") = 0;
".intel_syntax noprefix\n\t"
"RDTSC\n\t"
[CPUClock],
".att_syntax\n"
Sleep(1000);
".intel_syntax noprefix\n\t"
"RDTSC\n\t"
[CPUClock]\n\t"
[CPUClock],
".att_syntax\n"
CPUClock /= 1000000;
1) 可以嵌入C变量,但不能与寄存器的名称有冲突(注:__asm__后面的引号中的汇编名称必须为大写,否则可能编译出错)
2) 默认不是intel格式,所以开头要用宏指令声明为intel语法。
大部分情况下最好用GNU风格的汇编,
但有时需要移植Win32的汇编时可以考虑写成上面不伦不类的样子。
对应的vc6内嵌汇编是:
[CPUClock],
Sleep( 1000 );
[CPUClock]
[CPUClock],
CPUClock /= 1000000;
在VC6中汇编内嵌的C变量只要声明为函数的局部变量即可。
long CPUClock
problem 35: Win32程序中转至发布版时出现控件不能显示的情况。
那是因为使用CreateWindowEx这类函数创建控件时返回0。
原因是编译时出现警告:
LINK : warning LNK4089: all references to "comdlg32.dll" discarded by /OPT:REF
而控件类的创建是在comdlg32.dll中进行,忽略它将导致控件类不加载,引发错误。
解决办法是调用InitCommonControls(需要增加链接comctl32.lib)
同样原因,在使用RichEdit20A前要LoadLibrary("RICHED20.DLL")
problem 36: mingw gcc 4需要动态链接libgcc_s_dw2-1.dll
怀疑mingw的开发者想加入一些全局的功能(?),例如strace。
解决办法是在gcc后面使用-static-libgcc编译开关。
如果用TDM-GCC则没有此问题。
MinGW升级到4.5.2生成的exe需要libgcc_s_dw2-1.dll和libstdc++-6.dll ? 写道
-static-libgcc在 gcc/g++ 或 ld 中加上这个参数, 就可以不用 libgcc_s_dw2-1.dll-static-libstdc++在 g++ 或 ld 中加上这个参数, 就可以不用 libstdc++-6.dll-static在 gcc/g++ 或 ld 中加上这个参数, 對所有的库都会采用静态链接的方式
problem 37: 如何修改CMakeLists.txt,使生成的VC工程可以链接C运行时库的多线程静态版(把/MD换为/MT)
例如,llvm-2.7的源码中的CMakeLists.txt有一个对MSVC的判断:
if( MSVC )
# List of valid CRTs for MSVC
set(MSVC_CRT
set(LLVM_USE_CRT "" CACHE STRING "Specify VC++ CRT to use for debug/release configurations.")
add_llvm_definitions( -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS )
add_llvm_definitions( -D_SCL_SECURE_NO_WARNINGS -DCRT_NONSTDC_NO_WARNINGS )
add_llvm_definitions( -D_SCL_SECURE_NO_DEPRECATE )
add_llvm_definitions( -wd4146 -wd4503 -wd4996 -wd4800 -wd4244 -wd4624 )
add_llvm_definitions( -wd4355 -wd4715 -wd4180 -wd4345 -wd4224 )
# Suppress 'new behavior: elements of array 'array' will be default initialized'
add_llvm_definitions( -wd4351 )
if (NOT ${LLVM_USE_CRT} STREQUAL "")
list(FIND MSVC_CRT ${LLVM_USE_CRT} idx)
if (idx LESS 0)
message(FATAL_ERROR "Invalid value for LLVM_USE_CRT: ${LLVM_USE_CRT}. Valid options are one of: ${MSVC_CRT}")
endif (idx LESS 0)
add_llvm_definitions("/${LLVM_USE_CRT}")
message(STATUS "Using VC++ CRT: ${LLVM_USE_CRT}")
endif (NOT ${LLVM_USE_CRT} STREQUAL "")
后面加上这样的句子:
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
这里使用了regex replace把所有flags的/MD替换为/MT。
problem 38: strdup or _strdup ?
如果在Windows下,建议用_strdup,
如果在Linux下,建议用strdup。
实际上这个函数不是太好,建议最好别用。
problem 39: ISO 'for'内的局部变量
例如在for(int i=1; i & 10; i++)这样的循环外继续使用变量i会导致cygwin警告
提示添加-fpermissive
所以最好把int i移到循环之前,以兼容不同的编译器。
problem 40: cygwin用new创建变长的字符串可能未初始化为0
char *buffer = new char[size + 1];
buffer[size] = 0;
最后一句是确保末尾的0(只有Cygwin有必要)
VC6和Linux可以不写最后那句buffer[size] = 0;,
是因为new已确保整个数组内容已清零。
problem 41: VC6编译时出现interna use /Zm to specify a higher limit
原因是代码中出现很大的常量数组时:解决办法是在工程右键-&Settings-&C/C++下方添加/Zm1500
MinGW没有此问题,但编译时较慢。
problem 42: 使用g++编译c++代码时无法使用stricmp
解决方法:C++不使用stricmp,而是使用strcasecmp(#include &cstring&),
problem 43:
为什么vc2008编译就提示找不到msvcr90d.dll
* 关闭增量链接(配置属性-&链接器-&常规)
* Project Properties -& Manifest Tool-& Use FAT32 Work-around 为Yes重新编译
参考自:http://bbs.csdn.net/topics/
problem 44:
getopt和getopt_long重入问题。
一般程序只能调用一次getopt或getopt_long,如果第二次调用,将无法获取参数信息。
解决办法是在调用之前对optreset和optind赋值为1(这两个变量声明在getopt.h中)
optreset = 1;
optind = 1;
problem 45:
fwrite返回值判断出错问题和原因
//代码只是大概意思,可能有误,仅参考用
if (fwrite(buffer, sizeof(unsigned char), nRead, file) != (size_t)(nRead)) {
fprintf(stderr, "error : %s .\n", strerror(errno));
如果出现不等于的情况(fwrite出错),与socket(网络套接字)的写入不同的是,不是因为写入数据不全,而是因为其它原因(例如,从strerror可以知道,因为磁盘空间不足),不要主观臆断。
另外,nRead似乎有范围限制(受限于size_t的大小,32位机器貌似最大为65536)
problem 46:
如果在模板参数中引用std标准库内的类型,必须加typename,否则编译可能会出错。
例如:假设vectorEx类继承std::vector,则
template&class T& bool vectorEx&T&::erase(T t) {
iterator it = begin();
要改写成:
template&class T& bool vectorEx&T&::erase(T t) {
typedef typename vectorEx&T&::
iterator it = vector&T&::begin();
而类内部的声明
pair&iterator, bool& insert(T t);
(可能)需要改写成(否则iterator可能会报找不到定义的编译错误,
相当于写成
std::pair&typename vectorEx&T&::iterator, bool& insert(T t)
注意typename的位置:
typedef typename vectorEx&T&::
typedef typename vectorEx&T&::const_iterator const_
typedef typename vectorEx&T&::size_type size_
pair&iterator, bool& insert(T t);
problem 47:链接exe时出现下划线符号强制链接成@符号
Warning: resolving _Sleep by linking to _Sleep@4Use --enable-stdcall-fixup to disable these warningsUse --disable-stdcall-fixup to disable these fixups
这个警告虽然会成功生成exe文件,但程序可能会崩溃。那是因为编译器不知道windows api函数Sleep是stdcall函数而非普通c函数,最好确保添加头文件以消除这个警告
#define WIN32_LEAN_AND_MEAN
#include &windows.h&
problem 48. -mthreads与mingwm10.dll
http://tkamogashira.users.sourceforge.net/sodan/tips/mingwcross.html
简单来说,如果使用-mthreads编译程序,就不能完全静态编译(需要动态链接mingwm10.dll)以保证多线程下的异常处理是正常的(好像还是因为兼容旧版本Windows,所以可以认为是mingw一个不完美的bug)。
这个问题出现在静态编译qt 4.3.5的时候(在configure的时候关闭C++异常机制可以避免链接mingwm10.dll)
一般的程序不使用C++异常或者不使用-mthreads就不会遇到这个问题。
problem 49:unresolved external symbol __iob
.cn/s/blog_5d890d070100fpj1.html
1、缺少libc.lib解决这个问题的方法是去掉链接到libc.lib,具体地点:项目-〉属性-〉配置属性-〉链接器-〉忽略特定库。2、unresolved external symbol __iob这个__iob找不到的问题费 了我大部分的时间。跟踪到stdio.h文件,发现那里有个关于iob的宏,终于搞定。加入一句话到.cpp文件中:extern "C" { FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]}; }
problem 50:匿名结构体
如果匿名结构体的形式是(非标准写法)
等效于(下面是gcc标准写法)
gcc需要在gcc后添加编译参数-fms-extensions
visual studio需要添加/wd4201 /wd4996参数
C4201: nameless struct/union,
C4996: This function or variable may be unsafe.
这样做是兼容微软的匿名结构体语法
匿名结构体的作用是允许struct B在指针取成员的语法上拥有struct A的所有成员(前提是不能有相同名字的其他成员),同时struct B*可以安全地强制转换成struct A*,实现类似C++的继承特性。
还有类似的做法是struct B拥有struct A*(是指针而非结构体),不过匿名结构体的好处是内存分配只需要做一次 。
详细请参考:
/teejii88/mgui
http://pingf./categories/4252/posts
添加problem 50
添加problem 49
修改problem 26
添加problem 46、47
添加problem 45
添加problem 44
添加problem 43
添加problem 41, 42
添加problem 38, 39, 40
添加problem 37
添加problem 36
添加problem 35
添加problem 34
修改problem 20
添加problem 33
添加problem 31、32
增加problem 29、30
增加开头的参考链接
补充problem 28
补充problem 25、26、27
补充problem 24
补充problem 22、23
补充problem 20、21
补充problem 19
补注WSAPoll的问题
补充problem 18
补充problem13:WSAPoll
补充problem 15,16,17.来自于mysql++编译的移植问题。
补充problem13中关于drizzle源码包中的poll实现
补充problem13使用msysDVLPR的情况
增加problem12, 13, 14
修改了problem11,补充了problem7和problem5
weimingtom
浏览: 218874 次
来自: 广州
谢谢博主,翻译得很好哦
牙痛的彼岸:痹!
总结得很简练清晰啊,学习了!
恩,同样期待,毕竟是一代经典

我要回帖

更多关于 win7 mingw安装 的文章

 

随机推荐