t e m p o r a l 
 d o o r w a y 

The Simplest DLL

 

Creating and using a DLL in C++ Builder is... incredibly simple.

From the IDE, pick File | New | DLL.

Save the resulting project. Unlike most C++ Builder projects, the project source is the DLL (for a normal application, there is a separate "project source"). So you don't need to create any other files. If you saved your project as SimpleDLL, then the following is what you should put in SimpleDLL.cpp:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
// Message about borlandmm.dll ommitted by the author
//

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
   return 1;
}
//--------------------------------------------------------------------------
extern "C"
{
   int __declspec(dllexport) TestDLLInterfaceFunction(int theParameter)
   {
      return theParameter;
   }
}

The lone function (TestDLLInterfaceFunction) is the entry point the DLL exports. If you want to keep a function unexported, and unavailable to callers, just leave off __declspec(dllexport)

To avoid having the DLL be generated with a leading "_" on each function exported, uncheck "Generate Underscores" in Project | Options | Advanced Compiler (BCB4 - may be in another place in other versions). However, the caller will generally expect underscores. You will need to make sure caller and callee are in sync. In C++ Builder, however, turning off underscores will generally cause problems for the rest of the calling program.

The extern "C" bracketing the function makes sure that it get a "C" language name rather than a C++ name. C++ names are "mangled" and include the types of the parameters as part of the function name. That is not a problem when you are calling a C++ DLL from a C++ program using a .lib file. It is a problem if a C++ DLL is being called from a C program, a Delphi program, or some other language.

Compile and link the DLL in normal fashion. Your project directory should now contain (among other things) SimpleDLL.dll

Now, you need to create an import lib to link with any program that wants to use the DLL. This is done with the simple command "implib SimpleDLL.lib SimpleDLL.dll" at the MSDOS command prompt. Make sure you run this from inside the directory. When you have you will have added SimpleDLL.lib to the contents of the directory.

Now create a simple new application with File | New Application. Here's the form:

And the .dfm, which you can paste the controls from onto your own form:

object MainForm: TMainForm
   Left = 209
   Top = 167
   Width = 264
   Height = 143
   Caption = 'MainForm'
   Color = clBtnFace
   Font.Charset = DEFAULT_CHARSET
   Font.Color = clWindowText
   Font.Height = -13
   Font.Name = 'MS Sans Serif'
   Font.Style = []
   OldCreateOrder = False
   PixelsPerInch = 120
   TextHeight = 16
   object ResultLabel: TLabel
      Left = 48
      Top = 64
      Width = 38
      Height = 16
      Caption = 'Result'
   end
   object InputLabel: TLabel
      Left = 16
      Top = 32
      Width = 75
      Height = 16
      Caption = 'Input To DLL'
   end
   object Result: TLabel
      Left = 104
      Top = 64
      Width = 3
      Height = 16
   end
   object Input: TEdit
      Left = 104
      Top = 24
      Width = 121
      Height = 24
      TabOrder = 0
      OnChange = InputChange
   end
end

And, the following simple .cpp code:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "MainFormUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;

extern "C" _
{
   int __declspec(dllimport) TestDLLInterfaceFunction(int theParameter);
}
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::InputChange(TObject *Sender)
{
   try
   {
      int InputNumber = Input->Text.ToInt();
      Result->Caption = String(TestDLLInterfaceFunction(InputNumber));
   }
   catch (...) // Fails if the input is not a number
   {
   };
}
//---------------------------------------------------------------------------

The above code simply contains a declaration of the function exported by the DLL (with the appropriate dllimport modifier, wrapped in an extern "C"{}), and a simple event handler for the TEdit that sends the integer to the DLL and returns the result. If the string is not a valid integer, an exception is thrown by the AnsiString ToInt function, and the DLL is not called.

Do not turn off generating underscores for the main program, but do add the .lib file you generated from the DLL project to this application project. Make sure to save this application project to the same directory as the DLL, because for the DLL to be successfully invoked it must be either in the current directory of the program or in a directory on the PATH environment variable (set in your autoexec.bat). Keeping it in the current directory keeps it simple.

Compile and run. That's it. If everything is working, then when you type a valid number, it will be displayed on the form, like this:

It's a simple as that.

Copyright © 2004 by Mark Cashman (unless otherwise indicated), All Rights Reserved