NO

Author Topic: About Creating Win32 DLL ..  (Read 8133 times)

paul

  • Guest
About Creating Win32 DLL ..
« on: August 09, 2008, 04:27:19 AM »
Hello,
I am new. Also new to DLL creation.
I have done my research and know about Exporting functions.
I found some example on the Wiki, but then modified it because I thought it was in error.
But then I realized I may have combined C with C++ syntax.

See code below:

*****************************************************
#define WIN32_LEAN_AND_MEAN  /* speed up */
 #include <windows.h>

// Exported function - adds two numbers
extern "C"  _declspec(dllexport)  double AddNumbers(double a, double b);


// DLL entry function (called on load, unload, ...)
BOOL  APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    return TRUE;
}
 
double AddNumbers(double a, double b)
{
    return a + b;
}

*****************************************************
Pelles Compile Error Message :
Building FirstDLLPelles.obj.
C:\C_Compiler\FirstDLLPelles.c(6): warning #2099: Missing type specifier.
C:\C_Compiler\FirstDLLPelles.c(6): error #2014: Empty declaration.
C:\C_Compiler\FirstDLLPelles.c(6): error #2001: Syntax error: expected ';' but found 'string constant'.
C:\C_Compiler\FirstDLLPelles.c(6): error #2156: Unrecognized declaration.
C:\C_Compiler\FirstDLLPelles.c(6): warning #2099: Missing type specifier.
C:\C_Compiler\FirstDLLPelles.c(16): error #2120: Redeclaration of 'AddNumbers' previously declared at C:\C_Compiler\FirstDLLPelles.c(6): found 'double __stdcall function(double, double)', expected 'int __stdcall function(double, double)'.
*** Error code: 1 ***
Done.
***********************************************************************

Please any help would be greatly appreciated!

Paul




JohnF

  • Guest
Re: About Creating Win32 DLL ..
« Reply #1 on: August 09, 2008, 08:33:45 AM »
You don't need that 'extern' - it is used in C++

Take out the extern "C"

  _declspec(dllexport)  double AddNumbers(double a, double b);

Also there is a wizard for creating DLL's which you might find useful.

John
« Last Edit: August 09, 2008, 08:37:14 AM by JohnF »

paul

  • Guest
Re: About Creating Win32 DLL ..
« Reply #2 on: August 09, 2008, 08:39:07 PM »
Thanks John,
After I removed extern C, it did compile to a DLL.
But I was wondering if you can help me some more.

I wish to call this from Visual Basic 6, and I found a link claiming certain things about VB6:
**********************************************************
http://www.mingw.org/MinGWiki/index.php/VB-MinGW-DLL

Example 1: A DLL for Visual Basic, Programmed in C or C++

NOTE : This description is only for Visual Basic 6, not DotNet.

    * Step 1: Create your DLL.

VB can only call __stdcall functions, not __cdecl functions. So we must export all our functions as __stdcall. Create a DLL with the following code template:

extern "C" // only required if using g++
{

__declspec (dllexport) void __stdcall FooBar (void)
{
  return;
}

__declspec (dllexport) DWORD __stdcall FooBarRet (DWORD MyValue)
{
  return MyValue;
}

__declspec (dllexport) BOOL __stdcall DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
                break;
        case DLL_THREAD_ATTACH:
                break;
        case DLL_THREAD_DETACH:
                break;
        case DLL_PROCESS_DETACH:
                break;
        }
        return TRUE;
}

} // extern "C"

When compiling, add "--add-stdcall-alias" to your linker flags. If you're passing linker flags via g++, it should be "-Wl,--add-stdcall-alias". This adds an undecorated alias for the exported function names that is simply the name of the function. By default, the functions are exported with an @nn appended to the function name.

The DllMain function is called by the system when your dll is loaded and unloaded from a process, as well as when threads attach and detach (I'm not sure what that means, but it's in the case statement). If you have anything important to do in your dll when these events occur, this is the place to do it. Initializing WinSock is a popular thing to do here so that the WinSock function calls don't all return 10093 -- WSANOTINITIALISED. If you don't export this function yourself, it won't be automatically exported as in Visual Studio.

    * Step 2: Call DLL from VB

Under VB, create the library call such as:

Private Declare Sub FooBar Lib "mydll" ()
Private Declare Sub FooBarRet Lib "mydll" (ByVal MyValue As Long) As Long

That's all. As an alternative, you can create a TypeLib, but that's another story.

*************************************************************************************************************

My Questions and comments below :



1) They claim that my function prototype has to be pre-fixed with:
__stdcall
For use with VB6, do you (or anybody) know this to be the case?

2) Also I have noticed on the internet, that some code uses one Underscore and more of them use two Underscores:
I used :  _declspec
Others above : __declspec

What is the reason for the difference in number of underscores?

3) Due to  your suggestion of a wizard, I did find it.
Thanks. Took some time though to analyze, I found it confusing until I looked at the Wizard.h file

Thanks again John really appreciated your input!!!

Paul

JohnF

  • Guest
Re: About Creating Win32 DLL ..
« Reply #3 on: August 10, 2008, 07:51:40 AM »
My Questions and comments below :

1) They claim that my function prototype has to be pre-fixed with:
__stdcall
For use with VB6, do you (or anybody) know this to be the case?

2) Also I have noticed on the internet, that some code uses one Underscore and more of them use two Underscores:
I used :  _declspec
Others above : __declspec

What is the reason for the difference in number of underscores?

3) Due to  your suggestion of a wizard, I did find it.
Thanks. Took some time though to analyze, I found it confusing until I looked at the Wizard.h file

Thanks again John really appreciated your input!!!

Paul


1. Yes, __stdcall is the default calling convention for DLL's weather for VB or others and also for Win32 apps. To check you project is compiled as _stdcall go to the menu 'Project/Project Options then Compiler tab', look at the Calling Conv: drop down and select _stdcall if it is not already selected.

2. _declspec or __declspec makes no difference, the compile allows both.
The difference is I assume just for convenience, typing one is easier than typing two

John
« Last Edit: August 10, 2008, 08:48:51 AM by JohnF »

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: About Creating Win32 DLL ..
« Reply #4 on: September 23, 2008, 09:15:19 PM »
From a standard C point of view, two underscores (followed by a lower case letter) are more correct than a single underscore for an extension like this. I think _declspec is the older name, and __declspec is the preferred (and "improved") name. The same goes for _cdecl vs __cdecl, and so on...

(a single underscore works if it's followed by an UPPERCASE letter, IIRC)
/Pelle