vb调用c的dll后出现内存不能读写的错误??

summy_0201 2004-12-23 11:29:55
在一个模块里声明了dll函数,并写了funtion,在其中调用了dll函数,并在主程序中调用了funtion,调试时调用dll函数时抱错“dll调用约定错误”,编译后,运行程序无此错误,但抱程序错误“内存不能读也不能写”?可以认定dll函数调用成功了,这是怎么回事啊?该怎么解决?
...全文
190 点赞 收藏 6
写回复
6 条回复
summy_0201 2004年12月27日
没办法了,我暂时在调用过dll后 On Error Resume Next了一下,问题解决。谢谢各位了。
回复 点赞
asmgirl 2004年12月25日
gz
回复 点赞
blueice12 2004年12月24日
方法1 : 调用那个函数完毕后,自己修复堆栈。

其实C调用和stdcall调用的差别就在于,c调用是调用者恢复堆栈,而stdcall是被调用者恢复堆栈。而VB在调用所有的dll函数的时候都是采用stdcall的方式。见下面的示意代码:

StdCall :

push arg2
push arg1
call func

这就是stdcall方式调用 func( arg1,arg2 )的代码

CCall:

push arg2
push arg1
call func
add esp,8

多出来的一句就是恢复堆栈的代码,注意,只要让esp + 4 * 参数个数,堆栈就可以恢复。

这样就需要在VB里面插入机器码来直接操作esp寄存器,具体如何插入汇编代码可以参看网上的文章。因为只是插入一句代码,所以也可以静态修改编译出的文件来实现。

方法2: 自己用VC重新包装那个dll,也就是在VC里面定义一个新的函数:

__stdcall func( arg1, arg2 )
{
oldfunc( arg1,arg2 );
}

这里要注意,oldfunc要声明为 cdecl约定的,然后把这个源文件编译成一个obj文件,连接到VB工程中。

当然,重新封装一个dll也是可以的,但是那样发布的时候就需要发布两个dll了,有点太麻烦。
回复 点赞
qiqi5521 2004年12月23日
//dll我是改不了的,是第三方的dll,我要在vb里用里面的函数!

如果这个DLL的函数不是 _stdcall ,那么最好不要用,即使勉强能用,但实际上会破坏系统堆栈的平衡

http://community.csdn.net/Expert/topic/3654/3654315.xml?temp=.1760675
回复 点赞
summy_0201 2004年12月23日
但如果我编译执行程序,则不会出现“dll调用约定错误”,而且dll函数调用成功啊,但是vb会提示“未设置对象变量”??肯定是一调用了dll函数,便会这样的,程序代码本身没问题啊!能告诉我怎么回事啊?被这个查不出来的错误快逼疯了!!

下面是dll的.h文件里的开头内容:
#ifdef __cplusplus
extern "C" {
#endif
这个就是那个调用声明吗?我不太懂,这是vb能调用的模式吗?如果不行,要怎么办?dll我是改不了的,是第三方的dll,我要在vb里用里面的函数!
回复 点赞
marckle 2004年12月23日
用c写的dll,调用约定要改成__stdcall,而不是却省的_cdecl*方式。

回复 点赞
发动态
发帖子
API
创建于2007-09-28

1196

社区成员

2.3w+

社区内容

VB API
社区公告
暂无公告