Solved

dlls and tstirnglist

Posted on 2001-07-17
14
212 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 

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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses
Course of the Month6 days, 13 hours left to enroll

623 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