NO

Author Topic: Win32 dynamic link library - need an example  (Read 20823 times)

codez1

  • Guest
Win32 dynamic link library - need an example
« on: September 13, 2011, 03:33:32 AM »
I am new. I have created a win 32 static library and it works fine. I would like to create a win32 dynamic link library. Do you have a minimum skeleton code for this and how do I call a dll function from my program. I am writing console applications right now.
« Last Edit: September 13, 2011, 03:38:32 AM by codez1 »

codez1

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #1 on: September 13, 2011, 03:45:42 AM »
Since I asked, I found the dll wizard and it helped setup basic code.

Is the code setup by the wizard, the bare minimum?

CommonTater

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #2 on: September 13, 2011, 06:01:30 AM »
Pretty close...  The absolute bare, not one byte extra, minimum is the DLLMain callback which is executed by LoadLibrary();

http://msdn.microsoft.com/en-us/library/ms682583(v=vs.85).aspx

Also give this a read...
http://msdn.microsoft.com/en-us/library/ms682589(v=vs.85).aspx


« Last Edit: September 13, 2011, 06:03:10 AM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Win32 dynamic link library - need an example
« Reply #3 on: September 13, 2011, 08:27:14 AM »
This example is just for making minimum dll without CRT (C runtime libraries).
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

//#pragma nodefaultlib
//BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved)
#pragma comment(linker, "/NODEFAULTLIB")
#ifdef _WIN64
#pragma comment(linker, "/ENTRY:DllMainCRTStartup")
#else
#pragma comment(linker, "/ENTRY:_DllMainCRTStartup@12")
#endif
BOOL WINAPI DllMainCRTStartup(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}
int __declspec( dllexport ) __stdcall SampleFunction(int a, int b)
{
MessageBox(0, "SampleFunction", "TestDLL", MB_OK);
return a * b;
}

To make normal DLL using crt-library you can create empty DLL project and insert your source files to it,
and polink.exe insert code for DllMain-function if it is missing.
Exported functions can be listed in DEF-file if you don't use that __declspec( dllexport ) definition.
« Last Edit: September 14, 2011, 10:10:47 AM by timovjl »
May the source be with you

codez1

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #4 on: September 14, 2011, 09:12:38 AM »
Ok, I will check out the links. As for the code, that helps also, thanks.

laurro

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #5 on: November 03, 2011, 01:43:08 PM »
/* first the dll ( myDll.dll ) in myDll.c */
#include <windows.h>

BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:  break;
        case DLL_THREAD_ATTACH:   break;
        case DLL_THREAD_DETACH:   break;
        case DLL_PROCESS_DETACH:  break;
    }
    return TRUE;
}

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

__declspec(dllexport) double  __cdecl plusF(double a, double b) {  return a + b;  }

/* end */

/* and , for test */
/* you must check in Project,Project options,Compiler,Enable Microsoft extensions */

#include <windows.h>
#include <stdio.h>

typedef int    (__cdecl *ProcAddress_1)(int,int      );
typedef double (__cdecl *ProcAddress_2)(double,double);

int main(void)
{
HINSTANCE testDll = LoadLibrary("myDll.dll");

ProcAddress_1 plusI =(ProcAddress_1) GetProcAddress(testDll, "plusI");
ProcAddress_2 plusF =(ProcAddress_2) GetProcAddress(testDll, "plusF");

int    a = plusI(100 , 50   );
double b = plusF(0.33 , 0.67);

printf( "\n\n     a + b = %d + %.2f = %.2f    test\n\n" , a , b , plusF ( (double) a , b ) );

FreeLibrary(testDll);

return 0;
}
 

drgott

  • Guest
Re: Win32 dynamic link library - need *another* example
« Reply #6 on: February 23, 2012, 03:54:54 AM »
still waiting for the lightbulb on this thread.  i've followed it and done some external research, but i can't get beyond the "unresolved external" error.

i come from the static .a unix environment.  .dll's are not completely alien, but this is my first try at building one and using one.

i have a simple project that makes one call to a function residing in my dll.
i used the .dll wizard to create a .dll with that one function.  i end up with a .lib, .dll and .exp file from the dll wizard.
the simple project adds the .lib file to the linker options.  when i build the project, i get the unresolved external error.

POLINK: error: Unresolved external symbol '_getTotal@8'.
POLINK: fatal error: 1 unresolved external(s).

i've copied the .lib to the \pellesc c\lib\win directory (which is the first choice in the project folders options).  i don't know what to do with the .dll or the .exp, but for the purposes of a build, i'm thinking the location of a .dll doesn't matter at this point.  so, is it the .exp?  who uses it?

i turned verbose mode on for linking, and, among others, i see:
Searching C:\Program Files (x86)\PellesC\Lib\Win\mydll.lib
so i know the .lib is at least found and being searched

the .def file has this line:
"MyExportFunction"=_getTotal@8         // <---- my function
and at the very end of the .exp file, i can see the name of my function.  so i'm guessing the .def and the .exp files are ok.

if podump /all on my .lib is supposed to show the name of my function, it doesn't.  do i have to tell the wizard something that i missed?  it seems to create all the necessary boilerplate without my telling it anything. 

as for the function itself, the example provided by the wizard was pretty much what i was going to do anyway, so i just left the code that was there.  i changed the name of the function if for no other reason than to make myself useful.  was that wrong?

thanks for pointing me in the right direction.

-go 

CommonTater

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #7 on: February 23, 2012, 04:16:38 AM »
Compile the DLL as a separate project.

Write a header with your DLL's exports in it and include it in your main project.
Tell the linker to link with the library.
Use LoadLibrary() to make sure the DLL is in memory...
Compile

Run...
Should work...

Take a look at a few Windows headers... and look up a few function calls in the SDK... the windows API is just a bunch of DLLs... so you should handle yours the same way windows does.


 
« Last Edit: February 23, 2012, 04:18:36 AM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Win32 dynamic link library - need an example
« Reply #8 on: February 23, 2012, 09:27:57 AM »
Quote
i changed the name of the function if for no other reason than to make myself useful.  was that wrong?
Because you change function name to undecorated form, you should use dynamic linking with LoadLibrary or tell linker what altername name is.
Examples:
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int __stdcall MyExportFunction(int a, int b);
typedef int (WINAPI MYEXPORTFUNCTION)(int a, int b);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
static MYEXPORTFUNCTION *MyExportFunction;
HANDLE hLib = LoadLibrary("TestDllNew.dll");
if (hLib) {
MyExportFunction = (MYEXPORTFUNCTION*)GetProcAddress(hLib, "MyExportFunction");
int rc = MyExportFunction(1, 2);
char szTmp[100];
wsprintf(szTmp, "return value: %d", rc);
MessageBox(0, szTmp, "TestDllNew2Test", MB_OK);
FreeLibrary(hLib);
}
return 0;
}
Code: [Select]
//TestDllNew.c
int __stdcall getTotal(int a, int b)
{
return a + b;
}
Code: [Select]
;TestDllNew.def
LIBRARY TestDllNew.dll
EXPORTS
"MyExportFunction" = _getTotal@8
EDIT:
Or this with import library:
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#pragma comment(lib, "TestDllNew.lib")
#pragma comment(linker, "/ALTERNATENAME:_MyExportFunction@8=MyExportFunction")

int __stdcall MyExportFunction(int a, int b);

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MyExportFunction(0, 0);
return 0;
}
« Last Edit: February 23, 2012, 10:18:20 AM by timovjl »
May the source be with you

CommonTater

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #9 on: February 23, 2012, 04:36:41 PM »
ii've copied the .lib to the \pellesc c\lib\win directory (which is the first choice in the project folders options).  i don't know what to do with the .dll or the .exp, but for the purposes of a build, i'm thinking the location of a .dll doesn't matter at this point.  so, is it the .exp?  who uses it?

Let me just add a note of caution here...  It is very unwise to pollute the Pelles C folders with project files... way too much risk of a name collision and way too much risk of losing needed files. 
 
If you need to indicate an outside path you can add it to the folders lists in your project options, so you would set those for your main project to also look in your DLL project's main folder.
 
(menu) Project -> Project Options -> Folders
 
I'm attaching an older project of mine that used a DLL... It shows one of several ways of doing this. You should be able to unzip this to a folder and get a good look at how it's setup... no promises that it will compile on your machine since it uses a couple of external private libs.

 
 
 
 
« Last Edit: February 23, 2012, 04:50:54 PM by CommonTater »

drgott

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #10 on: February 23, 2012, 06:43:04 PM »
thanks to CommonTater and to timovjl for timely responses.  still some issues.

to CommonTater:
"Compile the DLL as a separate project."
the .dll and the .exe are 2 separate projects.

"Write a header with your DLL's exports in it and include it in your main project."
i declared my function as an extern in the main project.  for the purposes of this test, that should be the same thing, no? 
 
"Tell the linker to link with the library."
i believe i have already done that.  as i indicated, i had told the linker to use my .lib in the project options.  and, as i indicated, the verbose output from the build shows that the .lib is being searched.

"Use LoadLibrary() to make sure the DLL is in memory..."
isn't LoadLibrary() a runtime call?  unresolved external is link time.  i don't get beyond link time.

thanks for mickey.zip.  i appreciate your comment about polluting the pelles c directories.  your mm.dll doesn't seem to have used the wizard.  it looks quite different from what the wizard generates.
no .def, no .lib.  as i ask below in this post: is the .dll wizard not actually supposed to be used for building a .dll?

--------------------------------------------------------------------------------------------------------------------------------
to timovjl:
thanks for all the examples - lots of work for you - but i want to continue to do what i always do: link with a .lib and have a corresponding .dll somewhere convenient.
if i have done something that prevents that - and judging by your suggestions, what i have done is seriously wrong - then i want to undo that and do it right.

you say:
"Because you change function name to undecorated form, you should use dynamic linking with LoadLibrary or tell linker what altername name is. "
ok, 3 things:
1) i realize LoadLibrary() is an option, and i have used it in other projects where the .dll was 3rd party, but i didn't have the unresolved external errors. 
and as just stated, i would like to be able to add a .lib to the linker options and build normally. 
2) you say i changed the function name to "undecorated form".  what i did was change "SampleFunction()" to "getTotal()" in the dllmain.c and .h.  i then changed "_SampleFunction@8" to "_getTotal@8" in the .def.  isn't that still "decorated"?  what's not decorated here? 
and
3) have i not told the linker what the alternate name is?  didn't i tell the linker what the alternate name was by linking with the .lib, which has the alternate decorated name?  this is what i'm not following.
 
your second example looks just like what i already see in my dllmain.c and .def. 
what you have in your example .def file:
LIBRARY TestDllNew.dll
EXPORTS
"MyExportFunction" = _getTotal@8


what i have in my .def file
my .def file:
LIBRARY "mydll"
EXPORTS
; TODO: Add your exports here!
"MyExportFunction"=_getTotal@8

why is your .def right and mine wrong?  this is what i don't get.

i'm guessing i could just build the sample .dll from the wizard as is and link to my test project, and it would work fine, but that doesn't help me see
how to build .dll's.  i can't have a .dll that only does 1 thing.  and i can't name all my library functions "SampleFunction()" because that's the only
name that works.

so, yes, i changed the function name in the files generated by the wizard, but i believe i kept the decoration, and the .dll builds without error. 
that should count for something, no?  what do i do if i don't want SampleFunction()?  are we saying i can't use the wizard because it's only meant
to build and export SampleFunction() and nothing else? 

i would like to fire up the .dll wizard, add a bunch of functions, save and build a .dll and have a .lib file with the exports and add it to the linker options, just like i do with every other project that i build.  is this doable? if so, what do i do differently?  i've seen an example for vc++.  it doesn't look terribly different from what the pelles c dll wizard generates.  is there something i have to do with the pelles c wizard that i'm missing?

using the .dll wizard to build mydll.dll, and having a function called getTotal(), what do i have to do beyond declaring the function and coding it?  let's say for argument's sake that i declare it in mydll.h and put the code in maindll.c  i'll just ignore SampleFunction() and leave it be.  is there a missing step in this scenario?  how did my .dll build without an error if i made an error?

thanks again and sorry to ramble on.
-go

   

CommonTater

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #11 on: February 23, 2012, 07:58:09 PM »
thanks to CommonTater and to timovjl for timely responses.  still some issues.

to CommonTater:
"Compile the DLL as a separate project."
the .dll and the .exe are 2 separate projects.

Ok... that's the right way since they are two separate (and different) executables.
 
Quote
"Write a header with your DLL's exports in it and include it in your main project."
i declared my function as an extern in the main project.  for the purposes of this test, that should be the same thing, no? 

Not exactly... all functions are "extern" by default.
 
What the header does (look at mm.h) is declare the function as __declspec(dllimport) ...  You can do this in your main program as well... but the header will be needed if you link to the DLL from other sources, anyway.
 
 
Quote

"Tell the linker to link with the library."
i believe i have already done that.  as i indicated, i had told the linker to use my .lib in the project options.  and, as i indicated, the verbose output from the build shows that the .lib is being searched.

Hmmmmm.... ??? 
 
Quote
"Use LoadLibrary() to make sure the DLL is in memory..."
isn't LoadLibrary() a runtime call?  unresolved external is link time.  i don't get beyond link time.

Correct... I just wanted to make sure you had it in there someplace.  The goal is to load the DLL at runtime.
 
Quote
thanks for mickey.zip.  i appreciate your comment about polluting the pelles c directories.  your mm.dll doesn't seem to have used the wizard.  it looks quite different from what the wizard generates.
no .def, no .lib.  as i ask below in this post: is the .dll wizard not actually supposed to be used for building a .dll?

The wizard is one way of doing it... I prefer to start from blank pages.  I consider the wizards to be "examples" of how it can be done.  But like all software, there's usually more than one way to do things. Plus you would be absolutely amazed how much you learn when you have to struggle for every byte... :D
 
The Def and Lib files are on my system... but the zip-files command didn't include them.  If you were to set it up and recompile it, it would produce them for you.
 
Quote
to timovjl:
thanks for all the examples - lots of work for you -

drgott ... trust me on this.... Although Timo's responses tend to be a bit terse, he is by far the more advanced programmer... I tend to defer to his wisdom on most things.
 
 
« Last Edit: February 23, 2012, 08:04:39 PM by CommonTater »

CommonTater

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #12 on: February 23, 2012, 08:49:20 PM »
@drgott....  I'm attaching the simplest DLL project I can think of...
Pay particular attention to the project settings.
Hope this helps.
 

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Win32 dynamic link library - need an example
« Reply #13 on: February 23, 2012, 09:08:52 PM »
If def file is this when creating dll
Code: [Select]
LIBRARY "mydll"
EXPORTS
; TODO: Add your exports here!
"MyExportFunction"=_getTotal@8
we need def file like this when creating import library
Code: [Select]
LIBRARY "mydll"
EXPORTS
; TODO: Add your exports here!
_MyExportFunction@8
Can anyone confirm this ?
« Last Edit: February 23, 2012, 09:12:22 PM by timovjl »
May the source be with you

CommonTater

  • Guest
Re: Win32 dynamic link library - need an example
« Reply #14 on: February 24, 2012, 03:04:47 AM »
If def file is this when creating dll
Code: [Select]
LIBRARY "mydll"
EXPORTS
; TODO: Add your exports here!
"MyExportFunction"=_getTotal@8
we need def file like this when creating import library
Code: [Select]
LIBRARY "mydll"
EXPORTS
; TODO: Add your exports here!
_MyExportFunction@8
Can anyone confirm this ?

Hi Timo ...

I don't know how much help I can be here.  When compiling Pelles always produces it's own .lib so I've never done it manually from a .def ... so, no, I don't believe the .def is actually necessary in this case.

However; from what I've seen on other sites, I do believe your setup is correct.