vs2010编译MySQL 5.5.15并生成安装包
1.准备:
a. 下载mysql-5.5.15.zip http://dev.mysql.com/downloads/mysql/
b. 下载较新版本的CMake并安装,我使用的是CMake 2.85
c. 下载bison并安装,注意安装目录不能有空格.http://gnuwin32.sourceforge.net/packages/bison.htm
2. 解压mysql-5.5.15.zip,修改sql\sql_locale.cc,因该文件中有很多vs2010不能识别的多国语言的字符编码,实验发现及时改变成任何utf8类型的编码格式仍不行,后发现vs2010有对UTF8兼容的bug,故只好修改该文件,让它暂时只支持en_US一种语言。
3.将bison安装目录中bin\m4.exe拷贝到mysql-5.5.15\sql目录,使其与sql_yacc.cc在同一个目录下,此问题为bison调用m4.exe时无法找到其路径,应该是cmakelist.txt的问题。期间可能还会发生m4.exe找不到GNUWin32包的动态库的问题,去GNUWin32找相应的库下载并拷贝到mysql-5.5.15\sql下。
4.cmake gui 下配置生成工程文件MySQL.sln.
5.控制台下进到MySQL.sln所在目录执行:
"c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" MySQL.sln /build RelWithDebInfo "c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" MySQL.sln /build RelWithDebInfo /project initial_database "c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" MySQL.sln /build RelWithDebInfo /project PACKAGE "c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" MySQL.sln /clean
至此如果没有异议会在MySQL.sln所在目录会找到_CPack_Packages\win32\ZIP,会有一个mysql-5.5.15-win32.zip和完整的安装包mysql-5.5.15-win32,这就是最终生成的可以使用的安装包了。
********************************************************************
updated for mysql-5.5.16:
同样是m4.exe生成sql_yacc.cc的问题,在此版本中,需要copy m4.exe及其依赖的动态库与MySQL.sln保持在同一个目录下。–2011-09-22
关于封装文件内存映射
1. c++/MFC 封装好的文件内存映射类 摘自http://hi.baidu.com/andywangcn/blog/item/90c16635e32b70bbd1a2d359.html 首先介绍内存映射文件操作——函数的用法以及先后执行顺序 // 第一步:创建文件 // 第二步:创建内存映射文件对象 // 第三步:获取内存映射文件对象视图 // 对 pData 指针进行读写操作 // 第四步:取消内存视图映射 // 第五步:关闭内存映射对象句柄 // 第六步:关闭文件句柄 =================================header file========================================= // MapFile.h : header file #if _MSC_VER > 1000 class CMapFile // Operations // Implementation }; //{{AFX_INSERT_LOCATION}} #endif // !defined(AFX_MAPFILE_H__D067E5C8_C4D7_4569_A6BB_9D651FB3F396__INCLUDED_) =========================================implementation file=========================== // MapFile.cpp : implementation file #ifdef _DEBUG ///////////////////////////////////////////////////////////////////////////// CMapFile::CMapFile() CMapFile::~CMapFile() ///////////////////////////////////////////////////////////////////////////// // 1:创建或打开一个文件内核对象: Open the file for reading and writing. // 由于hFile即使为INVALID_HANDLE_VALUE,下面的CreateFileMapping仍然可以正常运行, // 2:创建一个文件映射内核对象 DWORD dwFileSize = GetFileSize(hFile, NULL); // Create the file-mapping object. The file-mapping object is 1 character hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, if (hFileMap == NULL) // 3:将文件数据映射到进程的地址空间: m_pvFile = MapViewOfFile(hFileMap,/*FILE_MAP_WRITE*/FILE_MAP_READ,0,0,0);//获取映射文件在内存中的首地址 //CloseHandle(hFileMap);// 关闭内存映射对象句柄 // 4:既然我们通过pvFile得到了映象视图的起始地址,那么可以对视图做一些操作了: // ANSI版本: // 5:从进程的地址空间中撤销文件数据的映象: // 6:关闭文件映射对象和文件对象: BOOL CMapFile::CloseMapFile() 2. ShareMem #include <afxmt.h> struct RWStr { int readIndex; int writeIndex; }; class AFX_EXT_CLASS ShareMem { public: ShareMem(int bufNum, int bufSize, char* bufName,int* isSuc); //构造函数 ~ShareMem(); public: BOOL Read(LPVOID data); //读数据 BOOL Write(LPVOID data); //写数据 BOOL Release(); private: char* name; char* indexName; int size; int num; struct RWStr rw; CSemaphore* writeSemap; CSemaphore* readSemap; CMutex* rMutex; CMutex* wMutex; CMutex* pMutex; HANDLE buffer; HANDLE pointer; LPVOID pBegin; LPVOID pIndex; }; #include "stdafx.h" #include <iostream> #include <string> #include "ShareMem.h" using namespace std; /* int bufNum //要申请缓存的数目 int bufSize //每个缓存的大小,在写入和读取数据时,以bufSize为单位 char* bufName //缓存的名称,每个缓存必须有唯一的名称 int* isSuc //输出参数,构造成功(*isSuc)为0,失败则为-1 */ ShareMem::ShareMem(int bufNum, int bufSize, char* bufName,int* isSuc) { *isSuc=0; if(num<1024*100) num=1024*100; else num=bufNum; size=bufSize; name=bufName; char temp[100]; strcpy(temp,name); strcat(temp,"pointer"); indexName=temp; //cout<<indexName<<endl; //步骤一:调用CreateFile()函数,以适当的方式创建或打开一个文件核心对象; //步骤二:把CreateFile()函数返回的文件句柄作为参数,传给CreateFileMapping()函数, // 由 CreateFileMapping()函数创建一个文件映射核心对象的适当属性; pointer=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,sizeof(rw),indexName); if(pointer==NULL) { *isSuc=-1; return; } //步骤三:创建了文件映射核心对象后,调用MapViewOfFile()函数,告诉系统把文件的哪一部分映射到进程的地址空间中,以何种方式映射; if(!(GetLastError()==ERROR_ALREADY_EXISTS)) { pIndex=MapViewOfFile(pointer, FILE_MAP_WRITE,0,0,0); ZeroMemory(pIndex,sizeof(rw)); } else pIndex=MapViewOfFile(pointer, FILE_MAP_WRITE,0,0,0); memcpy((void*)&rw,pIndex,sizeof(rw)); //read互斥体 char* tempName=NULL; strcpy(temp,name); strcat(temp,"rMutex"); tempName=temp; rMutex=new CMutex(FALSE,tempName); //writ互斥体 strcpy(temp,name); strcat(temp,"wMutex"); tempName=temp; wMutex=new CMutex(FALSE,tempName); // strcpy(temp,name); strcat(temp,"pMutex"); tempName=temp; pMutex=new CMutex(FALSE,tempName); //writ信号量 strcpy(temp,name); strcat(temp,"write"); tempName=temp; writeSemap=new CSemaphore(num,num,tempName); //read信号量 strcpy(temp,name); strcat(temp,"read"); tempName=temp; readSemap=new CSemaphore(0,num,tempName); if(rMutex==NULL||wMutex==NULL||pMutex==NULL||writeSemap==NULL||readSemap==NULL) { *isSuc=-1; return; } buffer = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,num*size,name); if(buffer==NULL) { *isSuc=-1; //cout<<"Create Mapping Faile!"<<endl; return; } //步骤四:利用MapViewOfFile()函数返回的指针来使用文件数据; pBegin=MapViewOfFile(buffer, FILE_MAP_WRITE,0,0,0); } ShareMem::~ShareMem() { //步骤五:操作完毕后,调用UnmapViewOfFile()函数,告诉系统 撤销对文件映射核心对象的映射; BOOL unBuffer = UnmapViewOfFile( pBegin ); BOOL unIndex = UnmapViewOfFile( pIndex ); if(!(unIndex && unBuffer)) { //cout<<"Unmap Faile!"<<endl; } } /* 功能说明:释放资源 返回值: 操作成功则返回TRUE 操作失败返回FALSE */ BOOL ShareMem::Release() { HANDLE temp1 = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,num*size,name); HANDLE temp2 = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,sizeof(rw),indexName); if(temp1!=NULL&&temp2!=NULL) { //步骤六:使用CloseHandle()函数关闭文件映射核心对象; //步骤七:使用CloseHandle()函数关闭文件核心对象; CloseHandle(temp1); CloseHandle(temp2); } else return FALSE; if(rMutex!=NULL&&wMutex!=NULL&&writeSemap!=NULL&&readSemap!=NULL) { delete rMutex; delete wMutex; delete writeSemap; delete readSemap; } return TRUE; } /* 功能说明:从缓存读取数据,以bufSize为单位 参数说明: LPVOID data //所要得到数据的指针,读取具体数据结构时可先进行强制转换后再传入参数 返回值: 操作成功则返回TRUE,data保存所读取的数据 操作失败返回FALSE,data无定义 */ BOOL ShareMem::Read(LPVOID data) { readSemap->Lock(); pMutex->Lock(); memcpy((void*)&rw,pIndex,sizeof(rw)); LPVOID read=(LPVOID)((char*)pBegin+rw.readIndex*size); memcpy(data,read,size); //cout<<"Geted id: "<<*(int*)data<<" Read index:"<<rw.readIndex<<endl; rMutex->Lock(); rw.readIndex=(rw.readIndex+1)%num; rMutex->Unlock(); memcpy(pIndex,(void*)&rw,sizeof(rw)); pMutex->Unlock(); writeSemap->Unlock(); if(read==NULL) { //cout<<"Failed to Map(read): "<<GetLastError()<<endl; return FALSE; } return TRUE; } /* 功能说明:向缓存写入数据,以bufSize为单位 参数说明: LPVOID data //所要写入数据的指针,写入具体数据结构时可先进行强制转换后再传入参数 返回值: 操作成功则返回TRUE,data为写入的数据 操作失败返回FALSE,data无定义 */ BOOL ShareMem::Write(LPVOID data) { writeSemap->Lock(); pMutex->Lock(); memcpy((void*)&rw,pIndex,sizeof(rw)); LPVOID write=(LPVOID)((char*)pBegin+rw.writeIndex*size); memcpy(write,data,size); //cout<<"Thread id:"<<GetCurrentThreadId()<<" Write index:"<<rw.writeIndex<<endl; wMutex->Lock(); rw.writeIndex=(rw.writeIndex+1)%num; wMutex->Unlock(); memcpy(pIndex,(void*)&rw,sizeof(rw)); pMutex->Unlock(); readSemap->Unlock(); if(write==NULL) { //cout<<"Failed to Map(write): "<<GetLastError()<<endl; return FALSE; } return TRUE; } 3.CMemMapFile 1.53 http://www.naughter.com/memmap.html 4.Shared Memory--win32 programming http://comsci.liu.edu/~murali/win32/Main.htm |
映射文件Pointer.map
值得注意的是,如果你只在VC Project Setting对话框中打开Generate mapfile,还是不够的。因为你一定还要输出程序代码地址和源代码行号!!这非常的重要!
要得到这些信息,请在Project Options对话框中键入“/mapinfo:lines /mapinfo:exports”。请你一定要养成这种习惯!因为这不是默认设置。
我们得到的map文件大致如下,我删节了大多数输出:
Pointer
(应用程序名)
Timestamp is 3d4407a7 (Sun Jul 28 23:03:03 2002)
(时间戳)
Preferred load address is 00400000
(最佳装载基地址。非常重要的一个数据。不过一般都是这个数。)
Address Publics by Value Rva+Base Lib:Object
0001:00000250 _main 00401250 f Pointer.obj
(_main的虚地址)
Line numbers for .\Debug\Pointer.obj(E:\ Pointer\Pointer.cpp) segment .text
12 0001:00000250 14 0001:00000268 15 0001:0000026f 16 0001:00000276
18 0001:0000027f 20 0001:00000291 23 0001:000002a4 24 0001:000002a6
(这就是我们的Pointer.cpp所对应的程序代码行号和相对虚拟地址的对应表)
我们可以从中看到,最佳装载基地址是0x00400000,_main的虚地址是0x00401250,而0001:00000250又是什么意思呢?
0x00000250就是_main的相对虚拟地址(RVA)。
0x00010000就是PE头文件的大小,一般都是这个数。
所以虚地址就是这么算出来的:
0x00401250 = 0x00400000 + 0x00010000 + 0x00000250
虚地址 = 最佳装载基地址 + PE头文件的大小 + 相对虚拟地址(RVA)
通过_main的RVA的计算,我们也就知道了怎么计算崩溃地址0x00401279的RVA,是0x00000279,对吧?
然后,在这个MAP映射文件的“Line numbers for .\Debug\Pointer.obj(E:\ Pointer\Pointer.cpp) segment .text”这个行号段中查找这个地址。如你所看到的,只有16行对应的00000276和18行对应的0000027F,没有00000279呀?
没有17行的对应关系,说明17行是空行。
那么00000279就一定是16行的了!这样你不用看那个程序员的代码,就可以通知他:崩溃发生在你的Pointer.cpp的第16行了!很酷吧!
利用pexports和MSVC,制作在MSVC下能链接的MingW编译的动态库
以下为BAT文件的内容
rem 必须要先安装MinGW
rem 通过下面的命令,来设置环境变量,并且只在本过程中有效
set path==%path%;C:\MinGW\bin\
pause;
rem 执行下面的命令来编译,参考:http://blog.csdn.net/shania_wang/archive/2010/10/26/5966492.aspx
mkdir dll_bin
gcc -O2 -shared -Wall -Wl,–export-all-symbols -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -fno-strict-aliasing -DTCC_TARGET_PE -DLIBTCC -o dll_bin\libtcc.dll tcc.c
pause
rem 从dll导出 def文件, 参考:http://www.emmestech.com/software/pexports-0.43/download_pexports.html
pexports dll_bin\libtcc.dll > dll_bin\libtcc.def
pause
rem 调用VC的工程制造引出库,MinGW 的 dlltool制造出来的在release版本下无法引入
call “C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT”
LIB /def:dll_bin\libtcc.def /machine:i386 /out:dll_bin\libtcc_imp.lib
pause
摘自:http://www.cppblog.com/woaidongmao/archive/2011/06/30/149816.html
Codejock.Xtreme.Toolkit.Pro V15.0.1 VC6下的编译问题
1. Dialog type “Hello word!” application.
2. Fatal Error message:
Compiling…StdAfx.cppAutomatically linking with ToolkitPro1501vc60SD.libc:\program files\microsoft visual studio\vc98\mfc\include\afxtempl.h(61) : fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit c:\program files\microsoft visual studio\vc98\mfc\include\afxtempl.h(331) : see reference to function template instantiation ‘void __stdcall ConstructElements(class CXTPReportRecordItemControl ** ,int)’ being compiledError executing cl.exe.
3. 解决办法:
添加定义
#define _XTP_EXCLUDE_CALENDAR
#define _XTP_EXCLUDE_REPORTCONTROL
还不知VC6下为什么不能包含CALENDAR和REPORTCONTROL功能。