Link to home
Start Free TrialLog in
Avatar of nova2002
nova2002

asked on

Creating DLL for Delphi

Hi,

Anyone have any GOOD resources / examples about creating/accessing DLL for Delphi ?

I just want to learn it to create something like "plugin" feature for my application.

Thanks in advance.

Regards,
nova
Avatar of tkalchev
tkalchev
Flag of Germany image

Create DLL:

library my_dll;
uses ... ;

procedure Proc1;stdcall;
begin
 ...
end;

procedure Proc2 ( P1,P2 : PChar );stdcall;
begin
 ...
end;

function Func1 ( P1 : Integer ) : Integer;stdcall;
begin
 ...
end;

exports
  Proc1 index 0,
  Proc2 index 1,
  Func1 index 2;

begin
end;

Use a DLL :

....
procedure DllProc1 ( Param1,Param2 : aType ); [stdcall;] external 'dll_file_name.dll';
....

begin
 ...
 DllProc1 ( P1,P2 );
 ...
end.

stdcall directive is useful, when you will use the dll in another language ( not Delphi )
Avatar of whos_wee_dug
whos_wee_dug

Hi Nova,

If you check out this link on delphi.about.com, It's good a good beginners article on making a simple dll.


http://delphi.about.com/library/weekly/aa041100a.htm

Cheers,

whos_wee_dug
hello Nova2002,  since you seem to be new to making DLL's, here is some code for a very simple DLL and for the program that calls it, I rarely use the stdCall calling convention, brcause I do not need it.

Code for the DLL, notice I do not need the uses clause because I only use basic math operators, but is you use any functions from other units, like SysUtils, you will need a Uses clause -


library Demo1;

procedure MyProcedure(Input: Integer; var Output: Integer); export;
begin
{if you are going to send back a parameter, then you need the  var  in front}
OutPut := Input * 4;
end;

function MyFunction(Base, Mult: Integer): Integer; export;
begin
Result := Base * Mult;
end;

function StdCallFunc(Input: Integer; var Output: Integer): Integer; stdCall; export;
begin
{the stdCall will tell the compiler to read the Parameters from Right-to-left
instead of the normal Pascal Left-to-right, this stdCall is needed for
a C-Language program, which will read parameters  Right-to-left}
Result := ((Input *5) - OutPut) div 2;
OutPut := (Input * 3)+ 20;

{I usually do NOT want my DLL to be used by any other program,
so I do not use the  stdCall  Calling convention}
end;

exports
 MyProcedure,
 MyFunction,
 StdCallFunc;

begin

end.


- - - - - - - - - - - - - - - - - - - - - - - - -

Here is some code for Two Button Clicks, the first one justs loads the DLL and tests for success, then gets the OutPut value from the MyProcedure. . . .
 the second one loads the DLL and does Two functions, one with the  stdCall  calling convention


procedure TForm1.sbut_LoadDllClick(Sender: TObject);
var
hLib, In1, Out1: Integer;
MyProcedure1: procedure(Input: Integer; var Output: Integer);
begin
hLib := LoadLibrary('Demo1.dll');
if hLib = 0 then
 begin
 ShowMessage('Error - Did not load the DLL');
 Exit;
 end;
@MyProcedure1 := GetProcAddress(hLib, 'MyProcedure');
if @MyProcedure1 = nil then
 begin
 FreeLibrary(hLib);
 ShowMessage('ERROR - MyProcedure1 is nil');
 Exit;
 end;
In1 := 22;
Out1 := 0;
MyProcedure1(In1, Out1);
ShowMessage('Out1 is = '+IntToStr(Out1));
FreeLibrary(hLib);
end;

procedure TForm1.sbut_LoadDll2Click(Sender: TObject);
var
hLib, In1, Out1, DResult: Integer;
MyFunction1: function(Base, Mult: Integer): Integer;
stdCallFunc1: function(Input: Integer; var Output: Integer): Integer; stdCall;
begin
hLib := LoadLibrary('Demo1.dll');
if hLib = 0 then
 begin
 ShowMessage('Error - Did not load the DLL');
 Exit;
 end;
@MyFunction1 := GetProcAddress(hLib, 'MyFunction');
if @MyFunction1 = nil then
 begin
 FreeLibrary(hLib);
 ShowMessage('ERROR - MyFunction1 is nil');
 Exit;
 end;
In1 := 122;
Out1 := 3;
DResult := MyFunction1(In1, Out1);
ShowMessage('Out1 is = '+IntToStr(Out1)+#10'Result is = '+IntToStr(DResult));
@stdCallFunc1 := GetProcAddress(hLib, 'StdCallFunc');
if @stdCallFunc1 = nil then
 begin
 FreeLibrary(hLib);
 ShowMessage('ERROR - stdCallFunc1 is nil');
 Exit;
 end;
DResult := stdCallFunc1(In1, Out1);
ShowMessage('Out1 is = '+IntToStr(Out1)+#10'Result is = '+IntToStr(DResult));
FreeLibrary(hLib);
end;


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

ask questions if you need more information
There is a Plugin component with the Jedi VCL open source component suite that you could use or base your own version off of.

http://jvcl.sourceforge.net/
Hi Nova2002,

Check out http://www.1delphistreet.com/vb/scripts/ShowCode.asp?txtCodeId=538&lngWId=7 this is a great example of creating/using *.dlls in Delphi
Avatar of nova2002

ASKER

Hi,

I tried using Slick182 example, and it's working. But when I 'exported' a function with string parameter and result, I got problem.

In my DLL, I created this function :

    function something (s: string) : string;
    begin
        result := 'hahahahaha';
    end;

In my application, I can load the DLL, I can call that function.

But, if I close my application (by clicking 'x'), I got error :

   Project DLLDemo.exe raised exception class EInvalidPointer with message "Invalid Pointer Operation".

Anyone how to fix it ? I put "ShareMem" unit on both.

This problem only when I use 'string' ?

Thanks
Replace String with PChar
Same result .. I changed it to PCHAR and I still got Invalid Pointer Operation when I closed my application.
ASKER CERTIFIED SOLUTION
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
AND. . . you will need to add


uses
  SysUtils;


to your library