Solved

Simple Example of Pchar in Delphi DLL

Posted on 2008-06-14
5
3,334 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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
A short article about problems I had with the new location API and permissions in Marshmallow
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

743 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now