🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.pascal.delphi.misc
4 messages
4 total messages Started by Le Doute Wed, 03 Mar 1999 00:00
Passing a string to a DLL procedure with PChar
#596
Author: Le Doute
Date: Wed, 03 Mar 1999 00:00
33 lines
2086 bytes
Hi,

I'm a certainly not an expert in object pascal, and I've just ran into some
trouble:

I need to convert one of my app (some kind of "utility") into a DLL to sell
what it does without selling its source (!). I can convert my app to a DLL
that would require only few inputs.

I need to pass to the DLL some strings. But ObjPascal has its own way to
manage strings which are not compatible with other compilers.  Using
ShareMem as Borland recommands isn't really what I want.

I have no experience with pointers so I would need some help:

My DLL needs to receive a string.

How can I export this string to the DLL through a pointer, and how do I
reconvert the pointer to a string inside my DLL? And "vice-versa", how can I
import a DLL output through a pointer.

For now, my code would look like this:

procedure ProcedureInsideTheDLL (Input:String; Output:String);




Thanks,

Louis Pelletier, Qu�bec

(I'm sorry for my english, BTW...)
Re: Passing a string to a DLL procedure with PChar
#597
Author: Emmanuel Derriey
Date: Thu, 04 Mar 1999 00:00
27 lines
1852 bytes
Hi !
I think that your procedure is :
procedure ProcedureInsideTheDLL (Input:String; var Output:String);
and not
procedure ProcedureInsideTheDLL (Input:String; Output:String);
Nevertheless, you should use PChar arguments ; you must consider that the
PChar are allocated by the caller.
Example :
procedure ProcedureInsideTheDLL (PcharInput:PChar; PCharOutput:PChar);    //
Don't need the 'var' keyword because it's a allocated pointer
var
  Input : string;
  Output : string
begin
  Input := string(PCharInput);    // string and PChar are compatible
// Do something
  PCharOutput := PChar(Output);
end;
It should work if enought char are allocated in PCharOutput !!! Else : BOOM
!
Hope it will help you...

--
Emmanuel Derriey.
Windows Software Developer.

e-mail : ederriey@at-iris.com
Re: Passing a string to a DLL procedure with PChar
#598
Author: Le Doute
Date: Thu, 04 Mar 1999 00:00
67 lines
3015 bytes
Emmanuel Derriey a �crit dans le message <7blh68$646$1@ai.alienor.fr>...
>Hi !
>I think that your procedure is :
>procedure ProcedureInsideTheDLL (Input:String; var Output:String);
>and not
>procedure ProcedureInsideTheDLL (Input:String; Output:String);

In fact... d'oh!

>Nevertheless, you should use PChar arguments ; you must consider that the
>PChar are allocated by the caller.
>Example :
>procedure ProcedureInsideTheDLL (PcharInput:PChar; PCharOutput:PChar);
//
>Don't need the 'var' keyword because it's a allocated pointer
>var
>  Input : string;
>  Output : string
>begin
>  Input := string(PCharInput);    // string and PChar are compatible
>// Do something
>  PCharOutput := PChar(Output);
>end;
>It should work if enought char are allocated in PCharOutput !!! Else : BOOM
>!
>Hope it will help you...


It does!

But one more question:

When I'm calling this procedure, what will I use? Something like:

ProcedureInsideTheDLL (PChar(Input); PChar(Output));
where Input, Output: String;

But it is possible that I will pass very long strings that way (like more
than 1MB)... so I'm concern about memory here:

PChar is a pointer? Right? So the DLL procedure will manipulate a shared
copy from the calling app. But when using PChar(MyString), am I making
actually a copy of my string?

And of course, inside the DLL, when using:

>  Input := string(PCharInput);

...I'm making yet another copy...

If my original string is 10MB long, I don't want, if possible, to use 20 or
30MB of RAM...

The main question here is: does PChar(String) gives a pointer to String, or
does it makes a C string copy of the original Pascal string (long string).

>--
>Emmanuel Derriey.
>Windows Software Developer.
>
>e-mail : ederriey@at-iris.com


Thanks again,

Louis Pelletier, Qu�bec.
Re: Passing a string to a DLL procedure with PChar
#600
Author: Tor Engebakken
Date: Fri, 05 Mar 1999 00:00
96 lines
3423 bytes
"Le Doute" <ledoute@sceptiques.qc.ca> wrote:

>Hi,
>
>I'm a certainly not an expert in object pascal, and I've just ran into some
>trouble:
>
>I need to convert one of my app (some kind of "utility") into a DLL to sell
>what it does without selling its source (!). I can convert my app to a DLL
>that would require only few inputs.
>
>I need to pass to the DLL some strings. But ObjPascal has its own way to
>manage strings which are not compatible with other compilers.  Using
>ShareMem as Borland recommands isn't really what I want.
>
>I have no experience with pointers so I would need some help:
>
>My DLL needs to receive a string.
>
>How can I export this string to the DLL through a pointer, and how do I
>reconvert the pointer to a string inside my DLL? And "vice-versa", how can I
>import a DLL output through a pointer.
>
>For now, my code would look like this:
>
>procedure ProcedureInsideTheDLL (Input:String; Output:String);
>
>
This procedure should be on the DLL-side: (It reads a string from a
indexed string resource of the dll. (Resource,res))

Main file:

library dllstr;
uses
  Loadres in 'LOADRES.PAS';
exports
  GetResource              index 1;

{$R *.RES}
{$R resource.res}
begin
end.

(Unit that actually contain the procedure)

UNIT loadres;

INTERFACE
var
 buffer:array[0..255] of char;

Procedure Getresource(i:integer;P:PChar); export;

IMPLEMENTATION
uses sysutils,winprocs;

Procedure Getresource(i:integer; P:PChar);
Begin
  LoadString(HInstance,i,Buffer,Sizeof(Buffer));
  StrCopy(P,buffer);
end;

end.

This should go on the calling side:

type
  Getresproc = procedure(i:integer;P:Pchar);
var
  Getres        : getresproc;

Function LoadDLL(dllname:string):boolean;
Var
  buffer:array[0..255]of char;
  entrypoint:TFarproc;

Begin
  entrypoint := nil;
  StrPCopy(buffer,dllname);
  DLLHandle:=LoadLibrary(buffer);
  If DLLHandle < 22 then
    result :=False
  else begin
    StrPCopy(buffer,'Getresource');
    EntryPoint:=GetProcAddress(DLLHandle,buffer);
    If Entrypoint=nil then
      result :=False
    else begin
      @Getres:=EntryPoint;
      result:=true;
    end;
  end;
end;

Hope this helps.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads