dll调用出错(50分)

  • 主题发起人 主题发起人 SunMoon
  • 开始时间 开始时间
S

SunMoon

Unregistered / Unconfirmed
GUEST, unregistred user!
自编了一dll,有一函数声明如下:
procedure jdesjm(mms:Pchar);
begin
......
end;

experts
jdesjm;

在程序中调用如下
procedure jdesjm(mms:Pchar)
stdcall;
function desjm(mms:string):string;

........

procedure jdesjm(mms:Pchar)
external 'desjm.dll' name 'jdesjm'
//第一种调用方式
function desjm(mms:string):string;
begin
jdesjm(pchar(mms))
result := ms;
end;
//第二种调用方式
function desjm(mms:string):string;
var
ms:pchar;
begin
ms:=pchar(mms);
jdesjm(ms)
result := strpas(ms);
end;

调用结果:
当调用这个函数任意一个结束后,程序无任何提示即退出,
通过跟踪调试发现dll函数调用后函数正常,但是在执行完调用函数后程序出现地址访问错误
即执行完 result := ms 或 strpas(ms) 到 end 后函数出错。
不知是什么原因
那位大侠指点一二,谢谢。


 
procedure jdesjm(mms:Pchar);
应该声明为:procedure jdesjm(var mms:Pchar);
传地址才对,否则就是传值了,当然不行。
 
tanglu:
pchar型传的就是地址,
我试过你的这种方式后发现此种方法在调试当中可看到返回结果,但是在调用函数结束后还是出现
地址访问错误。
我用原来的声明方式,去掉"stdcall"后函数调用正常,不知是什么意思。
若去掉"stdcall",在delphi中能使用,但在其他环境中能否正常,比如vc,vb等等;
在此谢谢您的答复,不知您还有其他的解释否。

欢迎各位大虾参加讨论。
 
弄清楚stdcall, pascal, cdecl方式的区别:)
 
Reboot:
大概知道一些,但现在还是不明白此种错误之原因,能否指点一下。
 
Reboot:
大概知道一些,但现在还是不明白此种错误之原因,能否指点一下。
 
我用原来的声明方式,去掉"stdcall"后函数调用正常,不知是什么意思。
若去掉"stdcall",在delphi中能使用,但在其他环境中能否正常,比如vc,vb等等;
在此谢谢您的答复,不知您还有其他的解释否。

-----问题不是明白着吗?
你的DLL里定义的这个procedure jdesjm(mms:Pchar);
没加stdcall指示字。

调用约定不一样



 
笑傲江湖:
您可能没有看明白,或许我没说明明白。我的意思如下。
在dll中没有格式如下
//第一种情况
library desjm;
......

procedure jdesjm(mss:pchar)
---没有声明,只有实现
begin
................
end;

exports
jdesjm
-----输出
begin
end;


调用unit
procedure jdesjm(mms:Pchar)
stdcall
----有 stdcall 函数desjm调用后出错,没有则正常。
function desjm(mms:string):string;

........

procedure jdesjm(mms:Pchar)
external 'desjm.dll' name 'jdesjm'
//第一种调用方式
function desjm(mms:string):string;
begin
jdesjm(pchar(mms))
----------调用dll函数
result := ms
----------能返回正常的结果
end
---------当有“stdcall”是出错,没有则正常
//第二种调用方式
function desjm(mms:string):string;
var
ms:pchar;
begin
ms:=pchar(mms)
-----------同上
jdesjm(ms)
---------同上
result := strpas(ms)
---------同上
end;


///第二种情况
library desjm;
......

procedure jdesjm(var mss:pchar)
---没有声明,只有实现, 增加 "var"
begin
................
end;

exports
jdesjm
-----输出
begin
end;


调用unit
procedure jdesjm(var mms:Pchar)
stdcall
----增加 "var" 有无stdcall 函数desjm调用后出错。
function desjm(mms:string):string;

........

procedure jdesjm(var mms:Pchar)
external 'desjm.dll' name 'jdesjm'
//第一种调用方式
function desjm(mms:string):string;
begin
jdesjm(pchar(mms))
----------调用dll函数
result := ms
----------能返回正常的结果
end
---------出错地址访问错
//第二种调用方式
function desjm(mms:string):string;
var
ms:pchar;
begin
ms:=pchar(mms)
-----------同上
jdesjm(ms)
---------同上
result := strpas(ms)
---------同上
end;

我的问题都已说明,即第一种情况当去掉“stdcall”是在delphi钟正常,其他环境不知道
第二种情况都不正常,所以我不知道问题出在什么地方,那位对此了解的兄弟帮忙解释解释。
thanks
 
library MinMax;
function Min(X, Y: Integer): Integer
stdcall;
begin
if X < Y then Min := X else Min := Y;
end;

function Max(X, Y: Integer): Integer
stdcall;
begin
if X > Y then Max := X else Max := Y;
end;
exports
Min,
Max;
begin
end.
看看DELPHI的例子,然后修改你的程序:
library desjm;
......
procedure jdesjm(mss:pchar)
stdcall;//加上STDCALL,那么在VC、VB中都可用STDCALL调用了
begin
................
end;
exports
jdesjm
-----输出
begin
end;


 
未指定调用方式时,按编译的缺省来定。
好象delphi时pascal吧,
c缺省的是cdecl,肯定和delphi不一样,所以要指定。
对于跨语言的调用,最好写清楚一点就不会错了
 
多人接受答案了。
 

Similar threads

后退
顶部