Discussion:
Simple example of creating a DLL?
(too old to reply)
Ned Banta
2004-08-30 23:12:25 UTC
Permalink
I mostly program in Fortran, but my current application needs to call code
written in C. I would like to use C++ Builder to generate a DLL containing
the C functions that will be called from the Fortran. Please excuse the
elementary level of my question, but can anyone provide a very simple
example of how a DLL, import library, and module definition file are
generated from C source code? Thank you.

Ned
Ed Mulroy [TeamB]
2004-08-31 00:55:31 UTC
Permalink
I have no Fortran compiler to try this with so here is a C++ program
which calls C language functions in a DLL.

Create the files that are shown. A command to build the program would
be

make -f project.mak
where the space after the -f and the extension .mak are optional.

----ProgCode.CPP------
#include <windows.h>
#include "dllcode.h"

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
char buffer[128];
int a = 3;
int b = 7;

wsprintf(buffer, "the sum %d + %d = %d",
a, b, Add2(a, b));
MessageBox(HWND_DESKTOP, buffer, "", MB_OK);

wsprintf(buffer, "the product %d * %d = %d",
a, b, Multiply2(a, b));
MessageBox(HWND_DESKTOP, buffer, "", MB_OK);

return 0;
}
-----DllCode.H--------
#ifndef DLLCODE_H
#define DLLCODE_H

/* if used by C++ code, identify these functions as C items */
#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllimport) int Add2(int a, int b);

__declspec(dllimport) int Multiply2(int a, int b);

#ifdef __cplusplus
}
#endif

#endif
-----DllCode.C--------
#include <windows.h>

/* pragma suppresses "calling argument not used" warnings */
#pragma argsused
BOOL WINAPI DllEntryPoint(
HINSTANCE hinst, DWORD reason, LPVOID reserved)
{
return TRUE;
}

__declspec(dllexport)
int Add2(int a, int b)
{
return a + b;
}

__declspec(dllexport)
int Multiply2(int a, int b)
{
return a * b;
}
-----Project.MAK-----------
# comments start with the pound symbol
# automatically check if a header file has changed
.autodepend

# -WR windows GUI exe dynamic linked (-W for static linked)
# -v generate debug info
progcode.exe : dllcode.lib progcode.cpp
bcc32 -WR -v progcode dllcode.lib

# create an import library
# -c case sensitive
dllcode.lib : dllcode.dll
implib -c dllcode.LIB dllcode.DLL

# C code does not need runtime type id or exception
# handling so they are suppressed with -RT- and -x-
# noeh32.lib stubs out any of those things found in
# the libraries, making the output file smaller
# -WDR windows dll dynamic linked (-WD for static linked)
# -v generate debug info
dllcode.dll : dllcode.c
bcc32 -WDR -v -RT- -x- dllcode.c noeh32.lib
--------------------------
C:\Documents and Settings\Administrator\My Documents\Projects\DllDemo
make -f project.mak
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -WDR -v -RT- -x- dllcode.c noeh32.lib
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
DLLCODE.C:
Turbo Incremental Link 5.66 Copyright (c) 1997-2002 Borland
implib -c dllcode.LIB dllcode.DLL

Borland Implib Version 3.0.22 Copyright (c) 1991, 2000 Inprise
Corporation
bcc32 -WR -v progcode dllcode.lib
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
PROGCODE.CPP:
Turbo Incremental Link 5.66 Copyright (c) 1997-2002 Borland

C:\Documents and Settings\Administrator\My Documents\Projects\DllDemo
--------------------------

The example above uses an import library instead of a module
definition file. Except for the import library probably being easier
to use they perform an equivalent function. You create a module
definition file with the impdef.exe tool and a command line similar to
this:

impdef DllName.DEF DllName.DLL

. Ed
I mostly program in Fortran, but my current application needs to call
code written in C. I would like to use C++ Builder to generate a DLL
containing the C functions that will be called from the Fortran.
Please excuse the elementary level of my question, but can anyone
provide a very simple example of how a DLL, import library, and
module definition file are generated from C source code? Thank you.
Ned Banta
2004-08-31 16:13:12 UTC
Permalink
Ed,

Thanks much for the example and the instructions. I can see that I could
have made a lot of guesses without stumbling on the solution.

Ned
I have no Fortran compiler to try this with so here is a C++ program which
calls C language functions in a DLL.
...
Ed Mulroy [TeamB]
2004-08-31 16:19:33 UTC
Permalink
Don't thank me yet. Build it on your machine and look at it running.
You've not received much value if you don't know from personal
experience that it works! <g>

. Ed
Post by Ned Banta
Thanks much for the example and the instructions. I can see that I
could have made a lot of guesses without stumbling on the solution.
Ned Banta
2004-08-31 18:33:46 UTC
Permalink
Ed,

I may not be much of a C programmer, but I have programmed in Fortran long
enough to know not to take anything for granted. With minor editing of the
make file to indicate the location of the Include and Lib directories, I was
able to compile and run the program you provided. It compiled and ran like
a charm. I also created a module definition file and verified that the
functions in the DLL show up there.

Ned
Post by Ed Mulroy [TeamB]
Don't thank me yet. Build it on your machine and look at it running.
You've not received much value if you don't know from personal experience
that it works! <g>
. Ed
Post by Ned Banta
Thanks much for the example and the instructions. I can see that I could
have made a lot of guesses without stumbling on the solution.
Ed Mulroy [TeamB]
2004-08-31 19:21:34 UTC
Permalink
FYI:

If you had to specify the locations for the include and library
directories then you probably need to go back and complete the
compiler installation. Look in the readme.txt file and create the
bcc32.cfg and ilink32.cfg files in the compiler's bin directory in the
manner is says.

It is good to hear that you got it running.

. Ed
Post by Ned Banta
I may not be much of a C programmer, but I have programmed in
Fortran long enough to know not to take anything for granted. With
minor editing of the make file to indicate the location of the
Include and Lib directories, I was able to compile and run the
program you provided. It compiled and ran like a charm. I also
created a module definition file and verified that the functions in
the DLL show up there.
Ned Banta
2004-08-31 22:42:41 UTC
Permalink
I went back and created the cfg files per instructions, and sure enough, I
no longer need the -I and -L options in the make file. Thanks again.

Ned
Post by Ed Mulroy [TeamB]
If you had to specify the locations for the include and library
directories then you probably need to go back and complete the compiler
installation. Look in the readme.txt file and create the bcc32.cfg and
ilink32.cfg files in the compiler's bin directory in the manner is says.
It is good to hear that you got it running.
. Ed
Post by Ned Banta
I may not be much of a C programmer, but I have programmed in Fortran
long enough to know not to take anything for granted. With minor editing
of the make file to indicate the location of the Include and Lib
directories, I was able to compile and run the program you provided. It
compiled and ran like a charm. I also created a module definition file
and verified that the functions in the DLL show up there.
It's me
2004-12-06 09:41:15 UTC
Permalink
Thank you for the example, Ed. I tried it and it works perfectly.

Thanks again.

--
It's me
Post by Ed Mulroy [TeamB]
Don't thank me yet. Build it on your machine and look at it running.
You've not received much value if you don't know from personal
experience that it works! <g>
. Ed
Post by Ned Banta
Thanks much for the example and the instructions. I can see that I
could have made a lot of guesses without stumbling on the solution.
It's me
2004-12-06 17:19:19 UTC
Permalink
Ed,

How would I specifiy the .def file using the command format you indicated?

I tried using the -c option with bcc32:

bcc32 -c -WDR -v -RT- -x- myproject.c

and then issued the command:

ilink32 @project.lnk

where project.lnk contains:

---------------------------
myproject.obj
myproject.dll
myproject.def
<list of libraries needed chained with '+'>

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

The linker complains that:

----------------------------
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Warning: Image linked as an executable, but with a .DLL or .BPL extension
----------------------------

and if I issue the implib command:

implib -c pymat13.LIB pymat13.DLL

I get:

-----------------------------
Borland Implib Version 3.0.22 Copyright (c) 1991, 2000 Inprise Corporation
Warning myproject.dll no exports
------------------------------

What should I do?

Thanks,

--
It's me



<snip>
Post by Ed Mulroy [TeamB]
bcc32 -WDR -v -RT- -x- dllcode.c noeh32.lib
--------------------------
<snip>
Post by Ed Mulroy [TeamB]
--------------------------
The example above uses an import library instead of a module
definition file. Except for the import library probably being easier
to use they perform an equivalent function. You create a module
definition file with the impdef.exe tool and a command line similar to
impdef DllName.DEF DllName.DLL
. Ed
Ed Mulroy [TeamB]
2004-12-06 19:29:51 UTC
Permalink
Post by It's me
myproject.obj
myproject.dll
myproject.def
<list of libraries needed chained with '+'>
Same thing as before. The commands for the linker are wrong.

ilink32.exe takes several fields of arguments on the command
line. Each field is separated from the one before (to the left of)
it by a comma. When you have told it all that you need then
you can end the command there - you do not need to supply
fields that you will not be using.

The fields are:

options and object file names
target file name
map file name
libraries
module definition file names
resource file names

No linker options were provided.

Linker options include the target type. It does not know if
you are trying to build an executable, a dynamic linked
library or a device driver. It does not know if you wish
case-sensitive linking, if incremental linking files are allowed
and if debug info is to be generated.

No startup code was given.

C and C++ programs use startup code to initialize the
program, call main, WinMain or DllEntryPoint, trap system
errors and shut down the program at the end.

The module definition file is listed in the place where the
map file name is to be specified.

I guess that a response file that was something like this
would be closer to correct:

/Tpd/aa/Gn/x/c c0d myproject
myproject,
<list of libraries needed chained with '+'>

Where the last three in the list of libraries are:
noeh32 import32 cw32i

Where those libraries are:

noeh32.lib - library to stub out exception handling and runtime
type id calls because 1-your program is C so has little use
for EH and RTTI and 2-you've already used -RT- -x- on the
compiler command line indicating you do not want them.
(others reading this note: do NOT do this for a C++ program
using classes or new/delete)

import32.lib - import library specifying what Windows provides

cw32i.lib - import library for the dynamic version of the compiler's
runtime library.

. Ed
Post by It's me
Ed,
How would I specifiy the .def file using the command
format you indicated?
bcc32 -c -WDR -v -RT- -x- myproject.c
---------------------------
myproject.obj
myproject.dll
myproject.def
<list of libraries needed chained with '+'>
---------------------------
----------------------------
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Warning: Image linked as an executable, but with a .DLL or
.BPL extension
----------------------------
implib -c pymat13.LIB pymat13.DLL
-----------------------------
Borland Implib Version 3.0.22 Copyright (c) 1991, 2000 Inprise Corporation
Warning myproject.dll no exports
------------------------------
What should I do?
Bob Gonder
2004-12-06 21:52:53 UTC
Permalink
Post by Ed Mulroy [TeamB]
/Tpd/aa/Gn/x/c c0d myproject
Ed meant to say c0d32
Ed Mulroy [TeamB]
2004-12-06 21:55:30 UTC
Permalink
Good catch - Thank you!

. Ed
Post by Bob Gonder
Post by Ed Mulroy [TeamB]
/Tpd/aa/Gn/x/c c0d myproject
Ed meant to say c0d32
It's me
2004-12-07 00:02:49 UTC
Permalink
Thanks Ed (and Bob).

I tried the suggestions and the earlier error message went away. I am now
able to use ilink32 to create the dll.

Onwards with the next battle. (Please see new thread).

--
It's me
Post by Ed Mulroy [TeamB]
Post by It's me
myproject.obj
myproject.dll
myproject.def
<list of libraries needed chained with '+'>
Same thing as before. The commands for the linker are wrong.
ilink32.exe takes several fields of arguments on the command
line. Each field is separated from the one before (to the left of)
it by a comma. When you have told it all that you need then
you can end the command there - you do not need to supply
fields that you will not be using.
options and object file names
target file name
map file name
libraries
module definition file names
resource file names
No linker options were provided.
Linker options include the target type. It does not know if
you are trying to build an executable, a dynamic linked
library or a device driver. It does not know if you wish
case-sensitive linking, if incremental linking files are allowed
and if debug info is to be generated.
No startup code was given.
C and C++ programs use startup code to initialize the
program, call main, WinMain or DllEntryPoint, trap system
errors and shut down the program at the end.
The module definition file is listed in the place where the
map file name is to be specified.
I guess that a response file that was something like this
/Tpd/aa/Gn/x/c c0d myproject
myproject,
<list of libraries needed chained with '+'>
noeh32 import32 cw32i
noeh32.lib - library to stub out exception handling and runtime
type id calls because 1-your program is C so has little use
for EH and RTTI and 2-you've already used -RT- -x- on the
compiler command line indicating you do not want them.
(others reading this note: do NOT do this for a C++ program
using classes or new/delete)
import32.lib - import library specifying what Windows provides
cw32i.lib - import library for the dynamic version of the compiler's
runtime library.
. Ed
Post by It's me
Ed,
How would I specifiy the .def file using the command
format you indicated?
bcc32 -c -WDR -v -RT- -x- myproject.c
---------------------------
myproject.obj
myproject.dll
myproject.def
<list of libraries needed chained with '+'>
---------------------------
----------------------------
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Warning: Image linked as an executable, but with a .DLL or
.BPL extension
----------------------------
implib -c pymat13.LIB pymat13.DLL
-----------------------------
Borland Implib Version 3.0.22 Copyright (c) 1991, 2000 Inprise Corporation
Warning myproject.dll no exports
------------------------------
What should I do?
Continue reading on narkive:
Loading...