Solved

dlls and tstirnglist

Posted on 2001-07-17
14
205 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
Comment Utility
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
Comment Utility
Or, I should think that you'd be able to use IStrings

GL
Mike
0
 

Author Comment

by:gutian
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
ok,let me try.thanks
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 21

Expert Comment

by:ziolko
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
hi epsylon:
   thanks,I' try it.
0
 
LVL 21

Expert Comment

by:ziolko
Comment Utility
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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

744 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now