DLL 中返回 PChar,在 VB 中调用时,太大会出错,为什么???(45分)

  • 主题发起人 主题发起人 netwinds
  • 开始时间 开始时间
N

netwinds

Unregistered / Unconfirmed
GUEST, unregistred user!
function f_enc_EncryStrHex(strSource:String;strKey:String):PChar;stdcall;
var
myenc:Tencript;
begin
myenc:= Tencript.Create(Application);
Result := PChar(myenc.EncryStrHex(strSource, strKey));
myenc.Free;
end;
这样在 delphi 调与与在 vb 中调用都可以,mydes.EncryStrHex 是一个加密的过程,不管它。但当加密的字符超长时,比如找度超过 10000 时,则在 delphi 与 vb 中都会出错。

后改成:

function f_enc_EncryStrHex(strSource:String;strKey:String):PChar;stdcall;
var
myenc:Tencript;
strTemp: array[0..300000] of Char;
begin
myenc:= Tencript.Create(Application);
StrLCopy(@strTemp,PChar(myenc.EncryStrHex(strSource, strKey)),300000);
Result :=@strTemp[0];
myenc.Free;
end;
之后在 delphi 中调用不会出错,再大都没问题。但在 vb 中调用却返回空,也不会提示错误。


请教,要怎么操作,才可在 delphi 与 vb 中都可返回正确的值。

高手在哪??????

没分了,帮个忙吧。

 
高手!!!!!!
 
高手呢?都哪去了?》???
 
function f_enc_EncryStrHex(strSource:String;strKey:String):PChar;stdcall;
var
myenc:Tencript;
strTemp: PChar;
begin
myenc:= Tencript.Create(Application);
GetMem(strTemp, 300000);
StrLCopy(@strTemp,PChar(myenc.EncryStrHex(strSource, strKey)),300000);
Result := strTemp;
FreeMem(strTemp);
myenc.Free;
end;
 
一样不行,而且在 dll 中不能使用 freememe()这一个函数,否则会出错。

我这是在DLL中的一段
 
function f_enc_EncryStrHex(strSource:String;strKey:String):PChar;stdcall;
你的函数这样写就有问题, VB里要用的话, 这两个参数应该用PChar, 而不能用string.你应该改成function f_enc_EncryStrHex(strSource:PChar; sourLen: integer;strKey:String; keyLen: integer):PChar;stdcall;
不过这样用的话, 如果字符串中有#0的话,你就要小心转换了,不然会被截断的.
 
to happylcq,

改成:
function f_enc_EncryStrHex(strSource:PChar;intSource:Longint;strKey:PChar;intKey:Longint):PChar;stdcall;
var
mydes:Tencript;
strTemp :PChar;
S1,S2:PChar;
begin
mydes:= Tencript.Create(Application);
GetMem(strTemp, 300000);
GetMem(s1,intSource);
StrLCopy(S1,strSource,intSource);
GetMem(s2,intKey);
StrLCopy(S2,strKey,intKey);
StrLCopy(strTemp,PChar(mydes.EncryStrHex(S1, S2)),300000);
Result :=strTemp;
//FreeMem(strTemp);
mydes.Free;
end;

之后,在DELPHI与VB中都可调用,但在 dll 中不能用 freemem释放,在VB中多调用几次就会出错,导致VB退出,怎么办???
 
改用WideString类型,VB和Delphi都可以自动支持。
 
widestring 也一样不行的。小一点的字串还可以,如果太长的话就出问题了。

有么就是在 delphi 没问题,在 vb 中有时会出错,有时不会。

 
这是怎么回事?怎么没人回答呢??????
 
高手呢????????/
 
调用freemem出错,说明你在操作内存时已经越界了.你好好检查一下, 先把mydes.EncryStrHex去掉试试看.
 
一样的,只要在 dll 中调用不着 freemem 就会出错。
mydes.encrystrhex 没有关系的。

不信你可以自己做一个dll,然后传入达到 20000 长度的字串,直接返回看看,一下子就错了。
 
我现在好好看了看你的这个程序,原来问题在这里你在DLL中分配了内存,并且返回了这块内存的指针,这时你freemem当然出错了.dll调用有个内存分配的原则:谁分配谁释放.所以我建议你这样写:
function f_enc_EncryStrHex(strSource: PChar; intSource: Longint; strKey: PChar; intKey: Longint;
pOut: pchar; outLen: integer): boolean; stdcall;
var
mydes: Tencript;
strTemp: string;
begin
mydes := Tencript.Create(Application);
try
strTemp := mydes.EncryStrHex(S1, S2);
if outLen >= length(strTemp) then
StrPCopy(pOut, strTemp)
else
Result := false; //调用程序分配内存太小
finally
mydes.Free;
end;
end;
在调用程序中分配pOut内存,释放内存.
 
最好的是Happylcq的回答,我也一直这样用
在我看,Windows的好多函数也是这样的
 
to happylcq

加密完的字符串 strtemp 肯定大于原字符串,那 outlen 要怎么个定法?无穷大?
要不返回就找不到值了?

你能够具体实现一个函数给我参考一下吗?针对特大字符集的
 
>>whyme,不好意思才看到你的提问,你要是在调用程序中实在不知道可能用到的内存大小,也可以在DLL中分配内存,不过一定要在DLL释放,所以你现写入一个释放内存的函数,并且有个全局的变量保存一下这个内存的句柄.像下面这样:
type
PPChar = ^PChar;
var
pOut: PChar;

...
function f_enc_EncryStrHex(strSource: PChar; intSource: Longint; strKey: PChar; intKey: Longint;
ppOut: PPChar; outLen: integer): boolean; stdcall;
var
mydes: Tencript;
strTemp: string;
begin
mydes := Tencript.Create(Application);
try
strTemp := mydes.EncryStrHex(S1, S2);
//分配内存
pOut := StrAlloc(Length(strTemp));
if outLen >= length(strTemp) then begin
StrPCopy(pOut, strTemp);
ppOut := @pOut;
end
else
Result := false; //调用程序分配内存太小
finally
mydes.Free;
end;
end;

procedure f_enc_FreeMemory;
begin
StrDispose(pOut);
end;
这样在在调用时先调用 f_enc_EncryStrHex,数据COPY完后再调用一下f_enc_FreeMemory.如果是多线程调用的话,这样写就有问题了.单线程这样用是没有问题的.
 
后退
顶部