我的程序需要用压缩解压缩,我找了个7ZIP压缩库源代码。里面没有生成LIB的,只有生成DLL,我建了个LIB工程,生成了一个在VC下建了个工程正常使用。转到汇编平台就不行了,卡死在LzmaCompress这个函数,LzmaCompress在大约230条指令的时候调用了HeapAlloc函数,就卡死在这个函数里。
PUSH ESI ;HeapSize ESI==5824
PUSH 8 ;Flags HEAP_ZERO_MENORY
PUSH DWORD PTR DS:[533258] ;hHeap
CALL DWORD PTR DS:[411018] ;HeapAlloc
hHeap是533258地址的一个双字变量,他是0,所以进入HeapAlloc大约20个指令内就出现访问越界。
我于是跟踪VC下编译的程序进入这个函数调用,发现hHeap【533258】指向的双字不是零,是00370000,结果是可以正常使用。
我重启VC下编译的程序,在【533258】设置了内存写入断点,结果发现在main函数没有调用之前,VC初始化代码设置了【533258】,用的是HeapCreate函数返回值。
查看汇编编译的程序,一直执行到HeapAlloc出错也没有设置【533258】的值,应为汇编没有像VC编译出程序那样的初始代码,而是直接就调用了start:开始处;
我重新进入VC添加了一些代码去除了VC自动添加的初始代码:
#pragma comment(linker, "/ENTRY:EntryPoint")
void EntryPoint()
{
ExitProcess(main());
}
设置从EntryPoint启动,结果一样出现了在HeapAlloc出错。甚至连printf都出错在HeapAlloc。
以上的VC下是控制台工程,我建了个WIN32工程一样是出错。我怀疑是不是那个LIB使用了类似NEW一样的C++操作符,所以导致必须要初始化代码,而汇编平台无法提供。但是我看他的代码都是.c结尾的,里面却调用了一些类似C++类的东西。他代码,
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));里的Alloc是objidl.h的
void *( STDMETHODCALLTYPE *Alloc )(
IMalloc * This,
/* [in] */ SIZE_T cb);
以后就查不到了。objidl.h 是用來放 COM 的核心宣告用的,以及 MIDL (Microsoft Interface Definition Language) 的宣告,這些東西和 COM Automation 有很密切的關係。是不是跟这个有关系??求解!
PUSH ESI ;HeapSize ESI==5824
PUSH 8 ;Flags HEAP_ZERO_MENORY
PUSH DWORD PTR DS:[533258] ;hHeap
CALL DWORD PTR DS:[411018] ;HeapAlloc
hHeap是533258地址的一个双字变量,他是0,所以进入HeapAlloc大约20个指令内就出现访问越界。
我于是跟踪VC下编译的程序进入这个函数调用,发现hHeap【533258】指向的双字不是零,是00370000,结果是可以正常使用。
我重启VC下编译的程序,在【533258】设置了内存写入断点,结果发现在main函数没有调用之前,VC初始化代码设置了【533258】,用的是HeapCreate函数返回值。
查看汇编编译的程序,一直执行到HeapAlloc出错也没有设置【533258】的值,应为汇编没有像VC编译出程序那样的初始代码,而是直接就调用了start:开始处;
我重新进入VC添加了一些代码去除了VC自动添加的初始代码:
#pragma comment(linker, "/ENTRY:EntryPoint")
void EntryPoint()
{
ExitProcess(main());
}
设置从EntryPoint启动,结果一样出现了在HeapAlloc出错。甚至连printf都出错在HeapAlloc。
以上的VC下是控制台工程,我建了个WIN32工程一样是出错。我怀疑是不是那个LIB使用了类似NEW一样的C++操作符,所以导致必须要初始化代码,而汇编平台无法提供。但是我看他的代码都是.c结尾的,里面却调用了一些类似C++类的东西。他代码,
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));里的Alloc是objidl.h的
void *( STDMETHODCALLTYPE *Alloc )(
IMalloc * This,
/* [in] */ SIZE_T cb);
以后就查不到了。objidl.h 是用來放 COM 的核心宣告用的,以及 MIDL (Microsoft Interface Definition Language) 的宣告,這些東西和 COM Automation 有很密切的關係。是不是跟这个有关系??求解!
解决方案 »
- win7下VS2005 MFC开发界面中文乱码怎么解决?
- 发布自绘菜单链接库(完整版)
- 问一个关于静态链接库的问题
- 求救,文件加密的问题,高手请进,急啊!!1
- 在派生自CWnd的窗口中动态添加标准控件的问题,大家来帮帮我啊
- 关于 Windows Media Format SDK 的小问题!
- 主对话框打开后马上打开一个模式对话框,该在哪个事件中执行此动作?
- 请阐述一下引用、句柄、指针 的异同以及对于资源的引用上的转换。
- ADO中,表中列数的查询及相关问题
- 如何改变CRichEditCtrl的背景(100分)
- 字节对齐是否影响对DLL的函数调用?
- This application has requested the Runtime to terminate it in an unusual way.
因此,如果需要在不使用c runtime初始化的工程,比如楼主的
#pragma comment(linker, "/ENTRY:EntryPoint")
void EntryPoint()
{
ExitProcess(main());
}
这样的工程中使用7z,就必须
1、手工初始化进程的堆(HeapCreate/CreateProcessHeap?实在记不清了),并且
2、重新定义7z源代码中的malloc/free,new/delete相关函数。
比如定义
void *malloc(size_t n)
{
return HeapAlloc(GetProcessHeap(), n);
}
void free(void *p)
{
return HeaapFree(GetProcessHeap(), p);
}
编译时忽略所有默认库,并链接malloc/free函数的obj文件。举例:
#pragma comment(linker, "/ENTRY:EntryPoint")
void EntryPoint()
{
// HeapCreate() // 初始化进程堆
void *p = malloc(1024*1024); // 进程堆没有初始化,执行失败
free(p);
}
回二楼:我指的是ASM工程。
回三楼:先谢谢你回答我的问题,我基本明白了。原来是汇编没有runtime初始化。
这下可麻烦了当初选错了,不应该用ASM,这个压缩库也比较变态你干嘛非要用RUNTIME啊,你不会直接用WINDOWS内存管理函数。
现在不知道如何在汇编下如何手动RUNTIME初始化!
2楼有附件LzmaLib.rar,大家帮帮我。
static void *SzAlloc(void *p, size_t size) { p = p; return Alloc(size); }
static void SzFree(void *p, void *address) { p = p; Free(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
我改成了
static void *SzAlloc(void *p, size_t size) { p = p; return MidAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MidFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
(孤陋寡闻了,还是第一次看到结构体成员是函数)
下面的2个函数MidAlloc,MidFree函数体用的是
VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
VirtualFree(address, 0, MEM_RELEASE);
而不是用malloc(size);free(address);
成功了,不调用RUNTIME函数,不会出现内存违规访问了。但是汇编不能用VC下编写的程序的RUNTIME还是个问题啊?!另外说一下,http://www.7-zip.org/sdk.html有下载LZMA压缩解压缩算法的代码C,C++,JAVA的都有,有需要压缩解压缩的可以去看看。
_fun@12不兼容?