MR Harris:
The cpp code that makes dll's in #16 does not use the switch case block. I have the example code from code blocks shown below. It looks like the sample code from powerbasic. I know it (your code) works, but why don't we have to do the same things the example code does? It seems that we just don't do it and it works anyway. We don't check for process or thread attach/ detach. Just wondering.
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
}
The switch/Select Case block is optional. In a real application there usually are initialization chores that need done, and the DLL_PROCESS_ATTACH / DLL_THREAD_ATTACH messages are sometimes a good place for that. Here's the basic dll example that has been in the PowerBASIC Help Manual for as long as I can remember...
An Example
A very simple example is a DLL with a function that will add one to any Long-integer passed to it as a parameter:
#COMPILE DLL
FUNCTION AddOne ALIAS "AddOne" (BYVAL x AS LONG) EXPORT AS LONG
AddOne = x + 1
END FUNCTION
...and it doesn't include that switch logic.
The boilerplate code both CodeBlocks and Dev-Cpp supplies is pretty slick though - even though I didn't use it. The basic idea is that the same header file can be used for functions exported from the dll or imported into the host through the use of a macro to properly define either the declspec(dllexport) or declspec(dllimport) attribute.
By the way - I checked out the price of Adobe Acrobat Pro - $450!!! I'm still smarting from buying Visual Studio Pro last summer!
Fred;
I made a unjustified assumption.
This is the block of code I thought came with the pb distribution sample code. Perhaps I got it from the forum. I keep it as a pbtpl in
the bin directory and forgot how I got it. I copied it from my version 8 installation when I upgraded. You see it looks very similar to the code blocks wizard code. I just assumed for some reason that is what was supposed to be used. It also looks like the 'skeleton' that is given in msdn. That must be why I thought you had to do it that way.
Here is the boiler plate from pb:
#COMPILE DLL
#DIM ALL
%USEMACROS = 1
#INCLUDE "Win32API.inc"
GLOBAL ghInstance AS DWORD
'-------------------------------------------------------------------------------
' Main DLL entry point called by Windows...
'
FUNCTION LIBMAIN (BYVAL hInstance AS LONG, _
BYVAL fwdReason AS LONG, _
BYVAL lpvReserved AS LONG) AS LONG
SELECT CASE fwdReason
CASE %DLL_PROCESS_ATTACH
'Indicates that the DLL is being loaded by another process (a DLL
'or EXE is loading the DLL). DLLs can use this opportunity to
'initialize any instance or global data, such as arrays.
ghInstance = hInstance
FUNCTION = 1 'success!
'FUNCTION = 0 'failure! This will prevent the EXE from running.
CASE %DLL_PROCESS_DETACH
'Indicates that the DLL is being unloaded or detached from the
'calling application. DLLs can take this opportunity to clean
'up all resources for all threads attached and known to the DLL.
FUNCTION = 1 'success!
'FUNCTION = 0 'failure!
CASE %DLL_THREAD_ATTACH
'Indicates that the DLL is being loaded by a new thread in the
'calling application. DLLs can use this opportunity to
'initialize any thread local storage (TLS).
FUNCTION = 1 'success!
'FUNCTION = 0 'failure!
CASE %DLL_THREAD_DETACH
'Indicates that the thread is exiting cleanly. If the DLL has
'allocated any thread local storage, it should be released.
FUNCTION = 1 'success!
'FUNCTION = 0 'failure!
END SELECT
END FUNCTION
But if you don't need to do initialization/cleanup stuff, you can simply use:
#COMPILE DLL