Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Why does this DLL call work?

Status
Not open for further replies.

sggaunt

Programmer
Jul 4, 2001
8,620
GB
I have to convert my shortstring parameters to PChar to ensure that my DLL will work with VB ??
Firstly the above statement true?

Anyway this is a converted function (in the DLL)

Code:
function RetrieveSettings(Code: integer): PChar; stdcall;
var S: string;
begin
   with datamodule2 do
   case code of
   0: S := Server.LocalName;
   1: S := inttostr(Server.DefaultPort);
   2: S := Server.Bindings[0].IP;
   3: S := inttostr(Server.Bindings[0].Port);
   4: S := Server.Bindings[0].PeerIP;
   5: S := inttostr(Server.Bindings[0].PeerPort);
   6: S := Server.Version;
   else S := 'Illegal Code';
   end;
   result := PChar(S);
end;

But the Delphi help on PChar seems to say that this should not work.

Code:
A common error when working with PChars is to store a local variable in a data structure, or return it as a value. When your routine ends, the PChar disappears because it is a pointer to memory, and not a reference counted copy of the string. For example:

function title(n: Integer): PChar;
var
  s: string;
begin
  s := Format('title - %d', [n]);
  Result := PChar(s); // DON'T DO THIS
end;

This example returns a pointer to string data that is freed when the title function returns.

But my fuction seems to be working is it because of the stdcall directive or do I need to change this?



Steve [The sane]: Delphi a feersum engin indeed.
 
if you use FastMM (And I think you do :), you can use normal strings and forget about PChar...

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Removed at present. I will put them back.

I have been experimenting with buho's answwer here thread102-1260513
But cannot get it to work.


Steve [The sane]: Delphi a feersum engin indeed.
 
I suppose more importantly will the dll still work with VB if its compiled with fastmm4?
Are shortstrings Ok as below?
BTW this code works fine as is when called from a delphi app.

e.g. In the DLL

Code:
// read the first line out of the stringlist and delete it!!

// read the first line out of the stringlist and delete it!!
function ReadLine: shortstring; stdcall;
var S: string;
begin
   if MemRecv.Count > 0 then
      begin
         S := MemRecv.Strings[0];
         Memrecv.Delete(0);
      end
   else
      S := 'NO DATA';

   Result := S;
end;

calling application

Code:
//declaration
function ReadLine: shortstring; stdcall; external prog;

// call
procedure TForm1.ReadBtnClick(Sender: TObject);
begin
  MessageBox.Text := ReadLine;
  RemCount.Caption := inttostr(ReadCount);
end;

Steve [The sane]: Delphi a feersum engin indeed.
 
suppose more importantly will the dll still work with VB if its compiled with fastmm4?

I think not, you need fastmm in both the DLL and the interfacing app.since you have VB on one side, it is no good.
so pchar it is. what problems are you having with buho's code?

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
This is adapted from buho's 'pure pascal' version I could not get the 'Delphi' version to work.

This works (almost) but only if I leave out the freemem(ret) call?

If its in I get 'Invalid pointer opertion'?
if removed fastmm4 reports a memory leak.


Code:
procedure TForm1.ReadBtnClick(Sender: TObject);
var Ret: PChar;
begin
   GetMem(Ret, 1024);          // Assign space
   FillChar(Ret^, 1024, 0);
   Ret := ReadLine;
   MessageBox.Text := Ret;
   RemCount.Caption := inttostr(ReadCount);
 //  FreeMem(Ret);
end;

Steve [The sane]: Delphi a feersum engin indeed.
 
use the delphi way:

Code:
------------------
Delphi way:
------------------
var
  Ret  : AnsiString;
  P : PChar;
begin
  SetLength(Ret, 1024);
  P:=PChar(Ret);
  P := Readline;
  MessageBox.Text := Ret;
  RemCount.Caption := inttostr(ReadCount);
end;

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Thanks daddy I will try that.

But it's all a bit academic for a while whilst our customer works out how to register a Delphi DLL (I don't know if he needs to do this anyway)?

As I understand it there should be no problems calling a Delphi DLL (see my full code posted earlier) from VB6.

But he has been trying to do this with VB.net, and his simple test DLL was written in Delphi studio 2006 for .net (and that has INDY 10) so my version would not compile, when he copied over the project.

To top it all we finally found out exactly what he wanted to do and we had it entirely the wrong way around the Client needs to be in the DLL and the Server in the hardware!!!




Steve [The sane]: Delphi a feersum engin indeed.
 
Our customer now has the Registration sorted out.
Sop back to the VB interface problem.

This doesnt work. looking at the Delphi don't do this example I would not think that it can?
I have add comments to see if I have the operation clear.
The function in the DLL must now return a PChar (to avoid a mismatch)

Code:
// read the first line out of the stringlist and delete it!!
// simplified for clarity.
function ReadLine: PChar; stdcall;
begin
   if MemRecv.Count > 0 then
      begin
         result := Pchar(MemRecv.Strings[0]);
         // debugging shows 'result' holds the correct string 
         //here 
         Memrecv.Delete(0);
      end
end;

Code:
Delphi way:
------------------
var
  Ret  : AnsiString;
  P : PChar;
begin
  SetLength(Ret, 1024); // assign space
  P:=PChar(Ret);        // make a pointer to the space
  P := Readline;        // as the funtion returns a pointer (PChar) this should now be a pointer to the string 
  MessageBox.Text := Ret;  // string get put in box ??
end;
Only I just get gibberish, perhaps because the example says that the returned pointer will be freed?



Steve [The sane]: Delphi a feersum engin indeed.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top