Title: Using a VC++ DLL with Delphi
Question: How can I call functions in a DLL compiled with VC++ (API style call) and how do I make a DLL in VC++ that was "compatible" with Delphi ???
Answer:
//---------------------------------------------------------------------------
// Author : Digital Survivor [Esteban Rodrguez Nieto | Jos Plano]
// Email : plmad666@gmail.com | jose.plano@gmail.com
// Web site : www.ds-studios.com.ar
// Module name: Main.pas
// Description : DLL call example
// Started : 07/20/03
//---------------------------------------------------------------------------
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TWND_Main = class (TForm)
procedure FormCreate(Sender : TObject);
private { Private declarations }
public { Public declarations }
end;
var
WND_Main : TWND_Main;
//---------------------------------------------------------------------------
implementation
{$R *.dfm}
// DLL functions import
// Here we define the functions we want to import form our DLL compiled with
// VC++, it's important to specify the type of "calling conventions", wich is
// the way that parameters are passed to functions (right to left, left to
// right, etc.). In this case I use stdcall a.k.a. "Standard Call", for more
// info about this you can search stdcall in Delphi documentation.
// We also need to declare the function as "external", that means that the
// function is obviously external (into de DLL file).
procedure SomeFunction (); stdcall external 'DLLSkeleton.dll';
// Here is a basic example procedure called "SomeFunction" that do nothing
// really
function AnotherFunction (value : integer) : integer; stdcall external 'DLLSkeleton.dll';
// Here is another example function called "AnotherFunction" that has an
// int parameter and returns another int value (retuns the parameter value
// really).
//---------------------------------------------------------------------------
procedure TWND_Main.FormCreate (Sender : TObject);
var a : integer;
begin
SomeFunction (); // Calls SomeFunction thats do nothing
a := AnotherFunction (100); // Puts AnotheFunction returned value into a
// AnotherFunction returns the same value passed by parameter, in this
// example we pass 100 and the functiton returns 100
if a = 100 Then WND_Main.Caption := 'I'm TRUE'
else WND_Main.Caption := 'I'm FALSE';
// An stupid way to test that all goes right :)
end;
//---------------------------------------------------------------------------
end.
*****************************************************************************
*****************************************************************************
An important note about VC++ DLLs:
Since VC++ compiler has an interesting way to decore functions names (signatures) it's important to know how to correctly avoid this decoration because Delphi don't recognize it if we compile the DLL with the default options of the VC++ compiler. Because of that I will add here the source example the DLL in VC++.
To avoid this decoration basically we need to add a .def file to the VC++ proyect with the name (signature) of the functions we want to export, and also we need to configure the VC++ compiler with this .def file like this:
Project Options - Linker - Input - Module Definition Files - Add .def file name.
The source of the DLL for VC++:
*****************************************************************************
*****************************************************************************
File "DLLSkeleton.cpp"
//---------------------------------------------------------------------------
// Author : Digital Survivor [Esteban Rodrguez Nieto | Jos Plano]
// Email : plmad666@gmail.com | jose.plano@gmail.com
// Web site : www.ds-studios.com.ar
// Module name : DLLSkeleton.cpp
// Description : Dinamyc link library skeleton
// Started : 07/20/05
//---------------------------------------------------------------------------
#include "DLLSkeleton.hpp"
//---------------------------------------------------------------------------
void __stdcall SomeFunction () {}
//---------------------------------------------------------------------------
int __stdcall AnotherFunction (int value) { return value; }
*****************************************************************************
*****************************************************************************
File "DLLSkeleton.hpp"
//---------------------------------------------------------------------------
// Author : Digital Survivor [Esteban Rodrguez Nieto | Jos Plano]
// Email : plmad666@gmail.com | jose.plano@gmail.com
// Web site : www.ds-studios.com.ar
// Module name : DLLSkeleton.hpp
// Description : Dinamyc link library skeleton
// Started : 07/20/05
//---------------------------------------------------------------------------
// Remember to include DLLSkeleton.def in PROJECT PROPERTIES - LINKER -
// INPUT - MODULE DEFINITION (or something like that)
//---------------------------------------------------------------------------
#ifndef DLL_SKELETOR_HPP
#define DLL_SKELETOR_HPP
//---------------------------------------------------------------------------
#include
//---------------------------------------------------------------------------
int __stdcall variable = 665;
void __stdcall SomeFunction ();
int __stdcall AnotherFunction (int);
//---------------------------------------------------------------------------
#endif
*****************************************************************************
File "DLLSkeleton.def"
LIBRARY DLLSKELETON
DESCRIPTION 'Dynamic link library demo'
EXPORTS
variable
SomeFunction
AnotherFunction
*****************************************************************************
*****************************************************************************
Another comment: You may noticed a variable exportation in the C++ code, but Delphi 7 doesn't support variable importing from DLLs. I don't know if version 8 has support for it.
I also puts the source code of the Delphi example and the source code of the DLL on my personal host, you can download from here:
http://planetgamer.com.ar/temp/DelphiDLL.zip
All the Delphi code was tested & compiled with Delphi 7.
All the C++ code was tested & compiled with M$ Visual Studio.NET 7.
Hope someone find this piece of code usefull. G00d luck.-
:B