老问题新问。关于delphi中类型和VB的关系。

1024office 2008-12-24 05:21:55
注意我的言辞哦。不是delphi的类型和VB类型的关系。
下面正题!
我用delphi写了一个DLL。Dll中有一个函数的申明如下:
function CheckSN(pData: PChar; iLen: Integer) : PChar; stdcall; export;
函数实体如下:
function MesCheckSN(pData: PChar; iLen: Integer) : PChar;
var i : integer;
sData : string;
sResult : String;
pResult : PChar;
begin
Try
......
......
pResult[0]:='A'
......
......
OK,程序就贴这么多,下面问题。
函数的接口调用全部OK,可以通过Debug测试出来。但是。
用delphi自己来呼叫这个Dll时,pResult[0]:='A'行执行OK。
用VB呼叫这个Dll时,pResult[0]:='A'行执行报地址访问错误。
向高手求解,这个问题的原理及解法。

高手现身啦,快快快!!!
...全文
183 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
1024office 2009-01-16
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 Avan_Lau 的回复:]
Delphi(Pascal) codevarp : pchar;
s : string;begins:='123';1GetMem(p,1);2p:=PCHAR(s);
p[0]:='4';end;
p所獲得的值同樣是指針,但第一種可通過下標訪問下一個地址,后面一種是無法訪問的。
[/Quote]
3Q.启发很大。结贴。回去测试。
ahjoe 2008-12-26
  • 打赏
  • 举报
回复
pResult 指到哪里去了?
金卯刀 2008-12-26
  • 打赏
  • 举报
回复
以上原因,應是內存分配區分為:系統區和用戶區的緣故。對于用戶申請的內存空間,放在用戶區,系統分配的,應該是在系統區。
常量字串‘123’,有系統分配內存并釋放,故p獲得其指針后,無法繼續訪問此地址的下一個地址!
而getmem,則不一樣,分配的在用戶堆中,用戶擁有足夠的權限訪問。

以上僅為個人理解,不足之處,請見諒并指正!謝謝!
金卯刀 2008-12-26
  • 打赏
  • 举报
回复

var
p : pchar;
s : string;
begin
s:= '123';
1 GetMem(p,1);
2 p:= PCHAR(s);
p[0]:='4';
end;

p所獲得的值同樣是指針,但第一種可通過下標訪問下一個地址,后面一種是無法訪問的。
金卯刀 2008-12-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 1024office 的回复:]
to:Avan_Lau
uses sharemem与否,结果一样呀。。。
[/Quote]

我意思是sharemem是borland專用的內存管理器,若dll只是給使用borland開發的程序使用,那ok。若有use,且由其他程序調用,有可能出現這樣的問題。uassign也解釋了。

運行時庫,都會被包含在dll或exe當中,除非是采用包模式開發的。應不是出在rtl的引用上。代碼本身問題的可能性較大,所以把相關的帖出來,問題比較容易查找到。畢竟不同的人,對所看到的表象,有不同的反應。
金卯刀 2008-12-25
  • 打赏
  • 举报
回复
在未對pResult進行任何顯式的內存分配或者指向某個數組,
運行類似pResult[0]:='A' ,意味著內存的動態分配,因為pResult[0]事先并不存在。
您的問題:delphi程序下可正常運行,vb程序下不能正常運行。我猜想(只是猜想),這內存的動態分配應該是delphi的運行時庫提供的,問題有可能出在運行時庫上面。若您懂得反匯編dll,觀察此段代碼實際情況,或許可以找到答案。或者在 《delphi源代碼分析》里,可以找到答案。

這里確認一點:您的dll程序,沒有uses sharemem吧?若有,也有可能造成這個問題。
qiume 2008-12-25
  • 打赏
  • 举报
回复
《Delphi 5 开发人员指南》中有VB和Delphi数据类型的对应关系......
1024office 2008-12-25
  • 打赏
  • 举报
回复
另外补充,如果采用对参数中的pchar类型,如上述的:pData变量进行pData[0]:='A';pData[1]:='B'这样的方式是可以执行的,不会有上述错误。
期待高手出现ing
OTZ
1024office 2008-12-25
  • 打赏
  • 举报
回复
to:kenshinggg
刚才试了,用PAnsiChar还是不行。一样报内存错误。

to:unsigned
我的问题不是出在给Result赋值上,而是出在给这个function内的一个变量数的某一位赋值上。pResult是一个变量。这种赋值方式在delphi的Exe调用时没有问题,但是用VB的Exe调用的时候就会出问题,当然,如果直接赋值pResult:='123456';这样的方式Delphi和VB的Exe是都可以的。

PS:个人感觉像是VB和Delphi对堆的操作模式不一样。不过又吃不准,不知道该如何下手确认这个事情,各位有没有什么其他高招了?
僵哥 2008-12-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 1024office 的回复:]
to:kenshinggg
刚才试了,用PAnsiChar还是不行。一样报内存错误。

to:unsigned
我的问题不是出在给Result赋值上,而是出在给这个function内的一个变量数的某一位赋值上。pResult是一个变量。这种赋值方式在delphi的Exe调用时没有问题,但是用VB的Exe调用的时候就会出问题,当然,如果直接赋值pResult:='123456';这样的方式Delphi和VB的Exe是都可以的。

PS:个人感觉像是VB和Delphi对堆的操作模式不一样。不过又吃不准…
[/Quote]
虽然你没有贴全代码,但是我可以想象一下你的pResult(也不知道是否有写错)应该是指向SResult吧?而sResult是一个栈变量,当函数执行完之后就会被释放,后果可想而知.而如果使用的是常量串'123456',是在程序的固定的位置当中不会被释放的,所以不管是VB还是Delphi都不会有问题.

[Quote=引用 7 楼 Avan_Lau 的回复:]
在未對pResult進行任何顯式的內存分配或者指向某個數組,
運行類似pResult[0]:='A' ,意味著內存的動態分配,因為pResult[0]事先并不存在。
您的問題:delphi程序下可正常運行,vb程序下不能正常運行。我猜想(只是猜想),這內存的動態分配應該是delphi的運行時庫提供的,問題有可能出在運行時庫上面。若您懂得反匯編dll,觀察此段代碼實際情況,或許可以找到答案。或者在 《delphi源代碼分析》里,可以找到答案。

這里確…
[/Quote]
ShareMem仅只在于Delphi/C++Builder DLL与Delphi/C++Builder Exe等之间有效,并且要求是所有相关用到共用内存的部分都要采用ShareMem.
edongxu 2008-12-25
  • 打赏
  • 举报
回复
可能是没有给pResult : PChar; 分配内存吧
GetMem(pResult,256);

pResult[0]:='A';
........
Free(pResult);

金卯刀 2008-12-25
  • 打赏
  • 举报
回复
把pResult[0]:='A'代碼之前,對pResult的任何操作(比如分配空間),都帖出來吧。不要告訴我們沒有哦。
1024office 2008-12-25
  • 打赏
  • 举报
回复
to:Avan_Lau
uses sharemem与否,结果一样呀。。。
success000 2008-12-24
  • 打赏
  • 举报
回复
mark
僵哥 2008-12-24
  • 打赏
  • 举报
回复
注意内存管理的问题.

不要通过返回值返回PChar类型的数据,通过参数返回,然后由主调用程序(如VB程序)分配好内存,然后在DLL当中进行改写.
panrongzeng 2008-12-24
  • 打赏
  • 举报
回复
所有的PChar改为PAnsiChar试试,
以前我搞dll给C#的时候遇到过这个问题,不知道你的是不是这个问题

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧