Solved

Simple Example of Pchar in Delphi DLL

Posted on 2008-06-14
5
3,373 Views
Last Modified: 2013-11-23
Hi,
I am trying to understand another area of Delphi, that of DLL's and Pointers. In the Documentation that i have read to date, it says that when passing strings to and from a function contained in an extermal  dll, that you either use strings of the shortstring type, or use a pchar as a pointer.

I seem to have some problem with Syntax however, as the following code gives me an error message when i try and compile it.

[E2010 Incompatible types: 'string' and 'PAnsiChar

what am i doing wrong ?
'
library test;
 
{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }
 
uses
  SysUtils,
  Classes,
  Registry,
  Windows;
 
{$R *.res}
 
function getMyDocumentsFolder():Pchar;stdcall;
var
  reg: TRegistry;
  MyDocumentsFolder: Pointer;
begin
  reg := nil;
  try
    reg := reg.Create;
    reg.RootKey := HKEY_CURRENT_USER;
    reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', false);
    MyDocumentsFolder := reg.ReadString('Personal');
  finally
    reg.free;
  end;
end;
 
exports
 GetMyDocumentsFolder;
 
begin
 
end.

Open in new window

0
Comment
Question by:slaterm1961
  • 2
  • 2
5 Comments
 
LVL 13

Accepted Solution

by:
ThievingSix earned 125 total points
ID: 21787679
Try(Assuming the result is MyDocumentsFolder):
library test;
 
{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }
 
uses
  SysUtils,
  Classes,
  Registry,
  Windows;
 
{$R *.res}
 
function getMyDocumentsFolder():Pchar;stdcall;
var
  reg: TRegistry;
  MyDocumentsFolder: String;
begin
  reg := nil;
  try
    reg := reg.Create;
    reg.RootKey := HKEY_CURRENT_USER;
    reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', false);
    MyDocumentsFolder := reg.ReadString('Personal');
    Result := PChar(MyDocumentsFolder);
  finally
    reg.free;
  end;
end;
 
exports
 GetMyDocumentsFolder;
 
begin
 
end.

Open in new window

0
 
LVL 2

Assisted Solution

by:dMa
dMa earned 125 total points
ID: 21788148
and do not foget to add ShareMem as the first unit in your uses.

uses
  ShareMem,
  SysUtils,
  Classes,
  Registry,
  Windows;
0
 

Author Comment

by:slaterm1961
ID: 21788453
Hi,
With The first bit of code, i was able to get the project to compile (haveing added ShareMem)  as suggested in Comment #2 but when i call the function from the other unit which has declared the function, i get an access violation error in the dll.

I declare the function as follows:


//This bit of code is just below the Uses clause of the form.
 
function getMyDocumentsFolder():string;stdcall external 'test.dll';
 
//And i call the function like this
 
var
 MyDocuments: String;
begin
 MyDocuments := GetMyDocumentsFolder;
 ShowMessage(MyDocuments);

Open in new window

0
 
LVL 2

Assisted Solution

by:dMa
dMa earned 125 total points
ID: 21788548
aaaahh i see

first of all you have an error in your getmydoc... function:

the problem is    
reg := reg.Create;

you sould use
reg := TRegistry.create ;
it wil lbe esaer for you to create at first an normal delphi application and test all you functions
after that create a new dll project and insert all you tested functions inside.

it is much easer to debug an application as an dll.










0
 

Author Comment

by:slaterm1961
ID: 21788726
Thanks for the help, that last comment fixed it.

I hope i split the points fairly between the two of you who assisted me :)

0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

Suggested Solutions

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

772 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