Hej
Jeg har arbejdet i C++ længe, men er nu gået tilbage i delphi og jeg har nu fået et problem.
Jeg har lavet en funktion, som fylder noget data ind i en buffer og returnere, men når jeg kommer tilbage til hvor jeg kaldte funktion er den tom, jeg har singlesteppet igennem og jeg er sikker på der kommer data i bufferen.
Her er functionen som det drejer sig om:
function receive(buff: pchar; len: integer): Integer; stdcall;
var
i,getlen: Integer;
tstr: String;
begin
if len > InLen then
getlen := InLen
else
getlen := len;
for i:=0 to getlen-1 do
begin
tstr := IntToHex(Byte(inBuffer[i]),2);
buff[i*2] := tstr[1];
buff[i*2+1] := tstr[2];
buff[i*2+2] := Char(0);
end;
RemoveFromBuff(getlen);
Result := getlen;
end;
Og her er så koden der kalder den :
var
l,i: Integer;
pr: String;
res: PChar;
begin
getMem(res,50);
l := Receive(res,20);
pr := '';
for i:=0 to (l*2)-1 do
pr := pr + res[i];
if Length(pr) > 0 then
Memo1.Lines.Add(pr);
FreeMem(res);
end;
Nogen der ved hvorfor? det burde jo være gemt når jeg kommer tilbage, eftersom en PChar er en pointer.
Kaspar
Hej Kaspar,
Som sådan ser din funktion rigtig ud.
Jeg har lige prøvet at se om det virker ved at lave et DLL med "receive" funktionen eksporteret og en applikation som benytter DLL'et. Dette fungere fint hos mig og den eneste forskel som jeg kan se det er at jeg ikke benytter funktionen "RemoveFromBuff(getlen);". Du har evt. en fejl i denne funktion. Det andet problem kunne være at du ikke får nul-stillet din PChar buffer fra starten af.
Du kan evt. bruge "res := AllocMem(50);" som automatisk nul-stiller indholdet af din pointer.
Når du ikke får nul-stillet din PChar, kan du opleve underlige ting hvis der ikke returneres nogle data fra Receice funktionen (evt. start med at sætte "buff[0] := #0;" som deet første i Receive).
Det skal sige at i mit test projekt har jeg oprettet InLen som Integer og InBuffer som PChar (med en predefineret streng så jeg kunne teste).
Bruger du DLL'et fra en Delphi applikation?
Det kunne også være at problemet måske har noget at gøre med at du bruger PWideChar i enten DLL'et eller applikationen. Her skal du bruge samme type, f.eks. hvis du bruger DLL'et fra VB så skal du bruge WideChar i Receive funktionen.
Her er koden som jeg har testet med:
DLL'et:
library Project2;
uses
SysUtils,
Classes;
{$R *.res}
var
InLen : Integer = 4;
InBuffer : PChar = 'abcdef';
function receive(buff: pchar; len: integer): Integer; stdcall;
var
i,getlen: Integer;
tstr: String;
begin
if len > InLen then
getlen := InLen
else
getlen := len;
for i:=0 to getlen-1 do
begin
tstr := IntToHex(Byte(inBuffer[i]),2);
buff[i*2] := tstr[1];
buff[i*2+1] := tstr[2];
buff[i*2+2] := Char(0);
end;
// RemoveFromBuff(getlen);
Result := getlen;
end;
exports
receive name 'receive';
begin
end.
Test applikationen:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function receive(buff : PChar; len : Integer) : Integer; stdcall; external 'Project2.dll' name 'receive';
procedure TForm1.FormCreate(Sender: TObject);
var
l,i: Integer;
pr: String;
res: PChar;
begin allocmem
getMem(res,50);
l := Receive(res,20);
pr := '';
for i:=0 to (l*2)-1 do
pr := pr + res[i];
if Length(pr) > 0 then
Memo1.Lines.Add(pr);
FreeMem(res);
end;
end.
Håber det hjælper.
/Michael.