Making DLL's from the Borland C++ Builder IDE

First we construct our good old DLL. Choose File->New, then select DLL Wizard. There are some options to set: Let the source be C++, don't use VCL, don't use Multi Threading, use VC++ Style DLL. Enter the source

extern "C" __declspec(dllexport) void myfun(int * a){*a = - *a; }

Save the project as "DLLproj"; save the source file as "MyMax". Then build the project, e.g. using CTRL-F9. You can't run the project because there is no main, so pressing F9 will result in an error.

Now we need a main project to call the DLL. Start a new Console application (File->New, choose Console Wizard). No need to include support for VCL or Mutli Threading. Then enter the source:

#include <iostream.h>

extern "C" __declspec(dllimport) void myfun ( int * a);

void main(int argc, char* argv[])
{
  int a = 6;
  int b = a;
  myfun(&b);

  cout << '-' << a << " er " << b << " ! \n";
}

Next, include the DLL in the project (Project->Add to Project). It is the .lib file (DLLproj.lib) that you need to include. Save the project. Then build the project and watch the fun begin. (To see the results, you probably need to run it from a DOS prompt).

Calling the DLL from R

This DLL happens to be ready to use from R. Start up an R session and execute

> setwd("c:/uht/cpp/dll-test/bcb2/") # ... or whereever you've placed the DLL
NULL
> dyn.load("DLLproj.dll")
> .C("myfun",as.integer(2))
Error in .C("myfun", as.integer(2)) : C/Fortran function name not in load table
> .C("_myfun",as.integer(2))
[[1]]
[1] -2
>

Right, the R session contains an error: I always forget that Borland for some strange reason changes the name from "myfun" to "_myfun" by default. To avoid the underscore from the IDE, choose Project->Options, then Advanced  Compiler, then uncheck "Generate underscores".

How to compile the DLL from the command line

Sometimes it's quicker to write the source in your favourite text editor and compile it using DOS commands, rather than starting up the IDE. This is especially so for the typical R DLL, which is just a little number cruncher. It  can be done with 

bcc32 -tWD -e"myfun.dll" myfun.cpp

asssuming that bcc32, the Borland C++ compiler, is in your search path. Yes, of course you can do this from Emacs with starting up a DOS shell, but that's another story. The -tWD option says to generate a DLL. The -e option gives the name of the executable image. To avoid the underscore in the generated symbol, add the -u- switch. No, I am not an expert in command line options and yes, I do think they're hard to figure out. They are documented in the help file "C++ Builder Tools".