Solved

dlls and tstirnglist

Posted on 2001-07-17
14
210 Views
Last Modified: 2010-04-06
I want to return a group string from a dlls,if I use tstringlist it tells me some error info.How can I do
0
Comment
Question by:gutian
  • 7
  • 4
  • 2
  • +1
14 Comments
 
LVL 21

Expert Comment

by:ziolko
ID: 6288877
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
 
LVL 6

Expert Comment

by:edey
ID: 6289877
Or, I should think that you'd be able to use IStrings

GL
Mike
0
 

Author Comment

by:gutian
ID: 6290813
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:gutian
ID: 6290843
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
 

Author Comment

by:gutian
ID: 6290870
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
 
LVL 13

Expert Comment

by:Epsylon
ID: 6291308
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
 

Author Comment

by:gutian
ID: 6292255
ok,let me try.thanks
0
 
LVL 21

Expert Comment

by:ziolko
ID: 6292295
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
 

Author Comment

by:gutian
ID: 6292392
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
 
LVL 21

Expert Comment

by:ziolko
ID: 6292502
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
 

Author Comment

by:gutian
ID: 6292716
hi ziolko,but if I add #0 end of the string,it show me the right string.why?
0
 
LVL 13

Accepted Solution

by:
Epsylon earned 200 total points
ID: 6292910
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
 

Author Comment

by:gutian
ID: 6293783
hi epsylon:
   thanks,I' try it.
0
 
LVL 21

Expert Comment

by:ziolko
ID: 6296937
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

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question