Creating a DLL
$DLL directive
Purpose: $DLL
tells BCX to generate code
for creating a "C" source code file for a Dynamically Linked Library that follows
the _cdecl calling convention used by most C and C++ compilers.
When creating a dynamically linked library that is to be called from an executable
created with BCX, $DLL
must be
the first line in your source code file.
EXPORT qualifier
The EXPORT
qualifer must be used by any SUB
or FUNCTION
which is to be called from a DLL by an external
program. If a SUB
or FUNCTION
will
be used only within the DLL, the EXPORT
qualifer is not to
be used. The EXPORT qualifier is to be used in both _cdecl and _stdcall DLLs and
only in a SUB
or FUNCTION
that the
programmer wants to expose to other programs.
Example 1: The example below will load and use an integer function from a DLL. It is in three sections, the DLL, a program to call the function from the DLL and a batch file to compile the programs.
The first section is the BCX DLL code. Cut and save this as C_DLL.bas
$DLL 'Must be the first statement FUNCTION SQUARED(A) EXPORT FUNCTION = A * A END FUNCTION
The second section is the program which will call the function in the DLL. Cut and save this as TestC_DLL.bas.
DIM Dll_Hnd AS HMODULE DIM Value% DIM i% !int __cdecl(*MyProc)(int); Dll_Hnd = LOADLIBRARY("C_DLL.dll") MyProc = (INTEGER(__cdecl *)(INTEGER))GetProcAddress(Dll_Hnd, "SQUARED") CLS FOR i% = 1 TO 10 Value% = MyProc(i%) PRINT i%, " squared = ", Value% NEXT FreeLibrary(Dll_Hnd)
Here, in the third section, is a batch file to translate, compile and link the C_DLL.lib and TestC_DLL.bas. Cut and save this as BuildC_DLL.bat and run it to compile the example.
CALL povars32.bat bc C_DLL pocc -W1 -Gd -Go -Ze -Zx -Tx86-coff C_DLL.c polink -dll -machine:ix86 -subsystem:console -OUT:C_DLL.dll C_DLL.obj bc TestC_DLL pocc -W1 -Gd -Go -Ze -Zx -Tx86-coff TestC_DLL.c polink -release -machine:ix86 -subsystem:console -OUT:TestC_DLL.exe TestC_DLL.obj C_DLL.lib
A SUB
or FUNCTION
using the EXPORT
qualifier will cause BCX to emit the appropriate prototype
(cdecl or stdcall) that will allow the procedure to be called internally within the DLL module
and, as well, externally by the calling process, which is usually an .EXE but also can be another DLL.
The following project demonstrates an example of this, where the FUNCTION XXUCASE$ is used internally in the MyDLL.dll by XUCASE$ and, as well, the FUNCTION XXUCASE$ is used externally by TestMyDLL.Bas.
Example 2: This first portion is the DLL code. Cut and save this as MyDLL.bas.
$DLL STDCALL FUNCTION XUCASE$(A$) EXPORT FUNCTION = XXUCASE$(A$) END FUNCTION FUNCTION XXUCASE$(A$) EXPORT FUNCTION = UCASE$(A$) END FUNCTION
This is a demo program which will load and use MyDLL.dll. Cut and save this as Test_MyDLL.bas.
DECLARE FUNCTION XUCASE$ LIB "MyDLL.DLL" ALIAS "XUCASE"(A$) DECLARE FUNCTION XXUCASE$ LIB "MyDLL.DLL" ALIAS "XXUCASE"(A$) PRINT "TESTING XUCASE$: ", XUCASE$("hello") PRINT "TESTING XXCASE$: ", XXUCASE$("hello")
Here is a batch file to translate, compile and link the MyDLL.lib and Test_MyDLL.bas. Cut and save this as Build_MyDLL.bat and run it to compile the example.
CALL povars32.bat bc MyDLL pocc -W1 -Gd -Gn -Go -Ze -Zx -Tx86-coff MyDLL.c polink -dll -release -machine:ix86 -subsystem:windows MyDLL.obj -OUT:MyDLL.dll bc Test_MyDLL pocc -W1 -Gd -Go -Ze -Zx -Tx86-coff Test_MyDLL.c polink -release -machine:ix86 -subsystem:console Test_MyDLL.obj -OUT:Test_MyDLL.exe
$DLL STDCALL directive
The $DLL
directive can be specified with the optional STDCALL
argument, $DLL STDCALL
which tells BCX to generate a "C" source code file for a dynamically linked library
that conforms to the _stdcall calling convention used by Visual BASIC and some other
compilers.
When compiling with the
$DLL STDCALL
and $CPP
directives or the$DLL STDCALL
directive and the command line -c flagan export file named "ProgramName.def" will be generated in addition to the normal BCX translator output.
Example 1: This first portion is the DLL code. Cut and save this as STDCALL_DLL.bas.
$DLL STDCALL FUNCTION WORLD$(A$) EXPORT LOCAL T$ T$ = A$ & ",World" T$ = UCASE$(T$) FUNCTION = T$ END FUNCTION
This is a demo program which will load and use a string function from the STDCALL_DLL. Cut and save this as Test_STDCALL_DLL.bas.
DECLARE FUNCTION Up$ LIB "STDCALL_DLL.dll" ALIAS "WORLD"(Param$) PRINT "Dll Result is: ", Up$("hello")
Here is a batch file to translate, compile and link the STDCALL_DLL.lib and Test_STDCALL_DLL.bas. Cut and save this as Build_STDCALL_DLL.bat and run it to compile the example.
CALL povars32.bat bc STDCALL_DLL pocc -W1 -Gd -Gn -Go -Ze -Zx -Tx86-coff STDCALL_DLL.c polink -dll -release -machine:ix86 -subsystem:windows STDCALL_DLL.obj -OUT:STDCALL_DLL.dll bc Test_STDCALL_DLL pocc -W1 -Gd -Go -Ze -Zx -Tx86-coff Test_STDCALL_DLL.c polink -release -machine:ix86 -subsystem:console Test_STDCALL_DLL.obj -OUT:Test_STDCALL_DLL.exe
Example 2: This an example which shows how a dll can call a callback function in an application. The first portion is the DLL code. Cut and save this as CALLBACK_DLL.bas.
$DLL
STDCALL
FUNCTION
MyDllFunction(
x$, foo(
b, a$)
AS
FUNCTION
BOOL
CALLBACK
)
AS
BOOL
EXPORT
DIM
z$ z$=
LCASE$
(
x$)
IF
foo(
1
, z$)
=
TRUETHEN
MSGBOX
"foo is true"
FUNCTION
=
TRUEEND
FUNCTION
Cut and save the following as Test_CALLBACK_DLL.bas. This is a demo program which will load the CALLBACK_DLL and have the dll call a callback function in the Test_CALLBACK_DLL.exe.
MyDllFunction(
LIB
"CALLBACK_DLL.dll"
,"little lamb"
, MyFoo)
PAUSE
FUNCTION
MyFoo(
a%, cc$)
AS
BOOL
STDCALL
" "
, cc$FUNCTION
=
TRUEEND
FUNCTION
Here is a batch file to translate, compile and link the CALLBACK_DLL.lib and Test_CALLBACK_DLL.bas. Cut and save this as Build_CALLBACK_DLL.bat and run it to compile the example.
CALL povars32.bat bc CALLBACK_DLL pocc -W1 -Gd -Gn -Go -Ze -Zx -Tx86-coff CALLBACK_DLL.c polink -dll -release -machine:ix86 -subsystem:windows CALLBACK_DLL.obj -OUT:CALLBACK_DLL.dll bc Test_CALLBACK_DLL pocc -W1 -Gd -Go -Ze -Zx -Tx86-coff Test_CALLBACK_DLL.c polink -release -machine:ix86 -subsystem:console Test_CALLBACK_DLL.obj -OUT:Test_CALLBACK_DLL.exe
For many more DLL example programs see the \BCX\DLL_Demo folder in the BCX distribution.