dlls and tstirnglist

I want to return a group string from a dlls,if I use tstringlist it tells me some error info.How can I do
gutianAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
EpsylonConnect With a Mentor Commented:
This is one way you can do it:


function myfun: PChar; external 'mydll.dll';
procedure releasebuffer(p: PChar); external 'mydll.dll';

procedure TForm1.Button1Click(Sender: TObject);
var p: PChar;
begin
// get the PChar string
  p := myfun;
// assign the string to the listbox's commatext property
  ListBox1.Items.CommaText := p;
// tell the dll to free the memory (the dll has to do this)
  releasebuffer(p);
end;


function myfun: PChar;
var sl: TStringList;
begin
// just create a strinlist
  sl := TStringList.Create;
// add some items
  sl.Add('Item1');
  sl.Add('Item2');
  sl.Add('Item3');
  sl.Add('Item4');
  sl.Add('Item5');
// allocate enough memory for the returning PChar
  Result := AllocMem(Length(sl.CommaText) + 1);
//copy the commatext value to the allocated buffer
  StrPCopy(Result, sl.CommaText);
  sl.Free;
end;

procedure releasebuffer(p: PChar);
begin
// the dll must free the allocated memory, not the main app
  FreeMem(p);
end;

exports
  myfun, releasebuffer;
0
 
ziolkoCommented:
gutian problem is that You want to use pascal strings (TStringList uses pascal strings), DLLs written in Delphi cannot use pascal strings.
Solve #1:
add ShareMem as first unit in Your library's USES clause AND your project's (select Project-View Source)
Solve #2:
give up with TStringList instead use array of WideString or
VarArrays
ziolko.
0
 
edeyCommented:
Or, I should think that you'd be able to use IStrings

GL
Mike
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
gutianAuthor Commented:
Thanks,Some stranges puzells me:
function someFun(tmp:integer):pchar;
var
  tmplst:TstringList;
   tmpStr:Ansistring;//if I use string then complied error
begin
  try
     tmpLst:=TstringList.create;
     ...
     for i:=0 to tmpLst.count-1 do
         tmpStr:=Tmpstr+tmpLst.strings[i];
  finally
     tmpLst.free   //if I free the TmpLst then no result //return
     result:=pchar(tmpStr);
  end;
end;
why???
0
 
gutianAuthor Commented:
Thanks,Some stranges puzells me:
function someFun(tmp:integer):pchar;
var
  tmplst:TstringList;
   tmpStr:Ansistring;//if I use string then complied error
begin
  try
     tmpLst:=TstringList.create;
     ...
     for i:=0 to tmpLst.count-1 do
         tmpStr:=Tmpstr+tmpLst.strings[i];
  finally
     tmpLst.free   //if I free the TmpLst then no result //return
     result:=pchar(tmpStr);
  end;
end;
why???
0
 
gutianAuthor Commented:
Thanks,Some stranges puzells me:
function someFun(tmp:integer):pchar;
var
  tmplst:TstringList;
   tmpStr:Ansistring;//if I use string then complied error
begin
  try
     tmpLst:=TstringList.create;
     ...
     for i:=0 to tmpLst.count-1 do
         tmpStr:=Tmpstr+tmpLst.strings[i];
  finally
     tmpLst.free   //if I free the TmpLst then no result //return
     result:=pchar(tmpStr);
  end;
end;
why???
0
 
EpsylonCommented:
gutian, use the TStringList.CommaText property. Pass this (null terminated) string from/to your dll as PChar and reconstruct the stringlist again by assigning the string back to the commatext property.
0
 
gutianAuthor Commented:
ok,let me try.thanks
0
 
ziolkoCommented:
gutian don't use PChar(tmpstr)!!! You will still recive memory access error.
If You want use PChar You have to:
GetMem(Result,size);
StrPCopy(Result,tempstr);
but easier way is to declare:
 function someFunc(...):WideString;
You can use WideStrings just like pascal string and there will be no error.
Then Your function:
function someFun(tmp:integer):WideString;
var
 tmplst:TstringList;
begin
 try
    tmpLst:=TstringList.create;
    ...
    for i:=0 to tmpLst.count-1 do
        Result:=Result+tmpLst.strings[i];
 finally
    tmpLst.free   //if I free the TmpLst then no  end;
end;

ziolko.

0
 
gutianAuthor Commented:
Epsylon,it's strange that I found if I return pchar(ansistring),then the last byte lost for example
function myfun():pchar;
begin
tmpstr:='kknd;kkng;';
result:=pchar(tmpstr);
end;
I call:
var
tmpstr:string;
tmpstr:=myfunc;
then
  tmpstr is 'kknd;kkng'#0
why?
and
sometime other function return is right.
gutian
0
 
ziolkoCommented:
PChar is null-terminated string thats why #0 is on the end last character - ; was removed probably 'cause there was not enough room in buffer
ziolko.
0
 
gutianAuthor Commented:
hi ziolko,but if I add #0 end of the string,it show me the right string.why?
0
 
gutianAuthor Commented:
hi epsylon:
   thanks,I' try it.
0
 
ziolkoCommented:
allocateing buffer was one of my previouse comments.
gutian > "why when add #0 on the end.." PChar is pointer to first character so as function parameter will be passed from this pointer to first byte in memory which code is 0, so when tmpstr is 'blahblah'#0 everything will be ok but when tmpstr is 'blah'#0'blah' as PChar will be passed only first 'blah'. Thats why PChars are called NULL-terminated strings.
ziolko.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.