Board index » delphi » Passing a string to a DLL procedure with PChar

Passing a string to a DLL procedure with PChar

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, Qubec

(I'm sorry for my english, BTW...)

 

Re:Passing a string to a DLL procedure with PChar


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 : ederr...@at-iris.com

Re:Passing a string to a DLL procedure with PChar


Emmanuel Derriey a crit dans le message <7blh68$64...@ai.alienor.fr>...

Quote
>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!

Quote
>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:

Quote
>  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).

Quote
>--
>Emmanuel Derriey.
>Windows Software Developer.

>e-mail : ederr...@at-iris.com

Thanks again,

Louis Pelletier, Qubec.

Re:Passing a string to a DLL procedure with PChar


Quote
"Le Doute" <ledo...@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.

Other Threads