GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 25-Nov-2005, 10:57
kobi_hikri's Avatar
kobi_hikri kobi_hikri is offline
Regular Member
 
Join Date: Apr 2005
Location: Israel
Posts: 431
kobi_hikri has a spectacular aura aboutkobi_hikri has a spectacular aura about

regarding dll creation and "work with"


Hey guys,

Just came back from army reserve, missed you guys ! (though I see Paramesh is taking care of all the threads I subscribed to )

The question :

Given the function prototype :

CPP / C++ / C Code:

   int do_something(int some_value); 


and say I implemented this function somehow - How do I create a dll that contains this function ? How do I use the function from the dll ?

Obviously (as you know me ... ), I am talking about ansi-c code only - if it matters.

Shabat shalom,
Kobi Hikri.
__________________
It's actually a one time thing (it just happens alot).
  #2  
Old 26-Nov-2005, 01:05
Paramesh's Avatar
Paramesh Paramesh is offline
Regular Member
 
Join Date: Sep 2005
Location: The Milky Way
Posts: 927
Paramesh is a jewel in the roughParamesh is a jewel in the roughParamesh is a jewel in the rough

How to create and use a DLL In a C program


Hi Kobi,

I just learnt how to create and use dll in files.

Here is what i found:
  • In Visual C++, create a new project.
  • In Visual C++ projects, select Win32 Project
  • In the application settings, choose the application type as dll and choose empty project
  • Now, create a header or source file with any name.
  • Inside the file, we have to enter the functions which we may use by loading the dll.
  • Suppose that we are calculating the factorial of a number.
  • So, the function prototype is like:
  • CPP / C++ / C Code:
    int fact(int n)
  • We have to include the text:
    CPP / C++ / C Code:
     extern "C" __declspec(dllexport)
    to indicate that we are going to use the function in dll.
  • Here is the file i have created:
    CPP / C++ / C Code:
     extern "C" __declspec(dllexport)
    int fact(int n)
    {
    	int i, fac;
    	for(i = 2, fac = 1; i <= n; i++)
    		fac*=i;
    	return fac;
    }
    
    .
  • Next, we have to create a def file, say fact.def.
  • In the def file, we should add:
    Code:
    EXPORT fact
    Because we are exporting the function fact in the dll.
  • Now, build the project. The dll will be successfully created if there is no errors.
  • The dll will be located in the debug folder of your project folder.
  • Now, copy the dll to windows/system32 folder.
  • All the work involving creating and exporting the dll is now finished.

Now, onto using the dll in our project.
  • Let us create a new console application with empty project.
  • Create a new source file.
  • We should include:
    CPP / C++ / C Code:
    #include<windows.h>
    to use the dll.
  • Then include the other header files needed.
  • Then, we have to create a function pointer like this:
    CPP / C++ / C Code:
     typedef int (*function)(int);
    where the first int is the return type and the int inside the braces is the argument.
  • This represents the prototype for a function.
  • Then, we shold create a new function to use it. Say the function name is fact. So,
    CPP / C++ / C Code:
     function fact;
    indicates that fact is the function which has return type int and one argument.
  • Then inside the main function, we should load the dll first.
    That is done by this statement:
    CPP / C++ / C Code:
           HINSTANCE hLib=LoadLibrary("fact.dll");  /* where fact is the name of the dll file*/
    
  • We should check whether the dll exists or not. We can check that by:
    CPP / C++ / C Code:
           if(hLib==NULL) 
           {
                printf("Unable to load library!");
                getchar();
                return 0;
           }
    
  • Then, we should get the module filename in the dll, which is done by this statement:
    CPP / C++ / C Code:
           char mod[50];
           GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, 50);
           printf( "Library loaded: %s\n", mod );
    
    where mod is the string which contains the path and name of the dll.
  • We should fetch the function in the dll. That is done by:
    CPP / C++ / C Code:
           fact=(function)GetProcAddress((HMODULE)hLib, "fact");
    
  • After fetching the function, we have to check whether the function exists or not.
    We are doing by this:
    CPP / C++ / C Code:
    if(fact==NULL)
    {
        printf("Unable to load function fact...\n");
        FreeLibrary((HMODULE)hLib);
        return 0;
    }
    
    
    If fact==NULL, then the function is not available.
    Then we should free the dll by using the statement:
    CPP / C++ / C Code:
                FreeLibrary((HMODULE)hLib);
    
  • Once we pass this stage, we are now ready to use the function fact.
    CPP / C++ / C Code:
     	   i = fact(5);
    	   printf("The factorial of 5 is %d",i);
    
    But this gives me a runtime error:
    Code:
    Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
    I dont know how to solve this one. I'll try to find out whats happening.
    But the factorial is calculated correctly and displayed in the window as 120!
  • Finally, we should free the dll.
Here is the full code for this source file:
CPP / C++ / C Code:
 #include <windows.h>
 #include <stdio.h>

 typedef int (*function)(int);

 function fact;

 int main()
 {
	   int i=0;	
       char mod[50];  

       HINSTANCE hLib=LoadLibrary("dedd.DLL");


       if(hLib==NULL) {

            printf("Unable to load library!");
            getchar();
            return 0;
       }

       GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, 50);
       printf( "Library loaded: %s\n", mod );


       fact=(function)GetProcAddress((HMODULE)hLib, "fact");
       
       if(fact==NULL)
	   {
            printf("Unable to load function fact...\n");
            FreeLibrary((HMODULE)hLib);
            getchar();
			return 0;
       }
		
	   i = fact(5);
	   printf("The factorial of 5 is %d",i);


       FreeLibrary((HMODULE)hLib);
	   getchar();
 }
 

This error comes only in Visual C++. Not in Dev C++.
Sorry about the error. I'm still googling to find out what is the error, and still unable to find out how to solve the error.
(I'm new too!)
Do anyone know how to solve this error?

Note that this is only one method of creating and using a DLL.

Regards,
Paramesh.
PS: Kobi, i have written from basics because everyone would understand
__________________

Don't walk in front of me, I may not follow.
Don't walk behind me, I may not lead.
Just walk beside me and be my friend.
  #3  
Old 26-Nov-2005, 12:27
kobi_hikri's Avatar
kobi_hikri kobi_hikri is offline
Regular Member
 
Join Date: Apr 2005
Location: Israel
Posts: 431
kobi_hikri has a spectacular aura aboutkobi_hikri has a spectacular aura about

Re: How to create and use a DLL In a C program


Hey Paramesh.

Thank you very much for your attention.


Quote:
Originally Posted by Paramesh
PS: Kobi, i have written from basics because everyone would understand

And I'm glad you did

Check this out : Simple dll
(this is actually what you explained, even less ... )
Here is something more like what you explained : Create and use dll

When you learned this topic, did your instructor teach you if we must include windows.h ?

Kobi.
__________________
It's actually a one time thing (it just happens alot).
  #4  
Old 27-Nov-2005, 03:16
Paramesh's Avatar
Paramesh Paramesh is offline
Regular Member
 
Join Date: Sep 2005
Location: The Milky Way
Posts: 927
Paramesh is a jewel in the roughParamesh is a jewel in the roughParamesh is a jewel in the rough

Re: How to create and use a DLL In a C program


Kobi,

The links you told were exactly what i referred.

and i found why the error comes up.
Because:
I declared the DLL with a different calling convention than the function pointer. In Visual C++, we have __cdecl and __stdcall calling conventions. We must declare your function pointer to match the proper calling convention as the DLL function.

The WINAPI i used is __stdcall, but the DLL function is a __cdecl function. I should make sure that the DLL and app both declare the DLL function as __cdecl or __stdcall (We have a choice in which one to fix). If we were to fix the DLL, we would do this:
CPP / C++ / C Code:
extern "C" __declspec(dllexport) __stdcall
fact(int n)
{
    int i, fac;
    for(i = 2, fac = 1; i <= n; i++)
        fac*=i;
    return fac;
}

Then the declaration of WINAPI for the function pointer in the app would match the DLL function's calling convention (in this case __stdcall).
If we want to change your DLL, then the app should declare a __cdecl function pointer (in this case,there is no need for the WINAPI -- just declare an "ordinary" function pointer (no WINAPI), since ordinary C functions are automatically __cdecl).

The calling convention determines how the parameters are passed to the function (which parameter actually goes first on the stack), and which function is responsible for cleaning up the stack. A mismatch in calling convention causes the error.

And we should check what is the name of the exported function.
It may vary. To see what the name is, we should use the Dependency Walker utility (depends.exe) and look at the exported names.

So, here is my final code:

DLL:
fact.cpp:
CPP / C++ / C Code:
extern "C" int __declspec(dllexport) __stdcall
fact(int n)
{
    int i, fac;
    for(i = 2, fac = 1; i <= n; i++)
        fac*=i;
    return fac;
}

fact.def:
Code:
EXPORTS fact

I used the dependency walker utility and found that the function name was: _fact@4 (because the return bytes is 4(int))


Calling program:
main.cpp

CPP / C++ / C Code:
#define WIN32_LEAN_AND_MEAN
#include<windows.h>
 #include <stdio.h>
typedef (WINAPI*function)(int);
function fact;

 int main()
 {
       int i=0;      
       char mod[50];

       HINSTANCE hLib=LoadLibrary("fact.dll");


       if(hLib==NULL) {

            printf("Unable to load library!");
            getchar();
            goto end;
       }

       GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, 50);
       printf( "Library loaded: %s\n", mod );


       fact=(function)GetProcAddress((HMODULE)hLib, "_fact@4");   /* note here.. the function name is _fact@4) */
       
       if(fact==NULL)
       {
            printf("Unable to load function fact...\n");
            FreeLibrary((HMODULE)hLib);
            goto end;
       }
        
       i = fact(5);
       printf("The factorial of 5 is %d",i);

       FreeLibrary((HMODULE)hLib);
end:
       getchar();
 }

The output came without any errors:
Code:
Library loaded: C:\WINDOWS\system32\fact.dll The factorial of 5 is 120

Note that the function name is found using the dependency walker utitlity, by opening the fact.dll.
The sample look at the fact.dll opened with the dependency walker utility is in the attachment:

Quote:
Originally Posted by Kobi
When you learned this topic, did your instructor teach you if we must include windows.h ?
I dont have an instructor!(I am Electrical engineering student).
Why did you ask this?

Regards,
Paramesh.
Attached Images
File Type: gif depends.GIF (26.8 KB, 6 views)
__________________

Don't walk in front of me, I may not follow.
Don't walk behind me, I may not lead.
Just walk beside me and be my friend.
  #5  
Old 27-Nov-2005, 05:08
kobi_hikri's Avatar
kobi_hikri kobi_hikri is offline
Regular Member
 
Join Date: Apr 2005
Location: Israel
Posts: 431
kobi_hikri has a spectacular aura aboutkobi_hikri has a spectacular aura about

Re: How to create and use a DLL In a C program


Quote:
Originally Posted by Paramesh
I dont have an instructor!(I am Electrical engineering student).
Why did you ask this?

Oh ..., I don't get it ... Why don't you have instructors ?
Anyway, my question about windows.h came because I'm looking for a way to create function library's (or something that will act like a function library) in my OS project, so that the user could use some built in functions (I will supply all of them).
I don't want to use windows.h for my OS
So, I asked about it because I assumed you learned this topic at class, and perhaps this point came up.

Do you suppose this is possible ?

Anyway, Paramesh - your help is appreciated and I'll have to re-think my design. (The problem with hobbies is that you never have enough time to dedicate to it - so this OS project is not advancing as I wish).

Well, if we're talking about time, then it's time for me to go to work

Kobi.
__________________
It's actually a one time thing (it just happens alot).
  #6  
Old 27-Nov-2005, 05:34
Paramesh's Avatar
Paramesh Paramesh is offline
Regular Member
 
Join Date: Sep 2005
Location: The Milky Way
Posts: 927
Paramesh is a jewel in the roughParamesh is a jewel in the roughParamesh is a jewel in the rough

Re: regarding dll creation and "work with"


Kobi,
Sorry about not using ANSI C.

Of course, we have instructors for all subjects. But since we dont learn C/C++ in detail(they taught us 2 years ago) , i told you that I dont have an instructor now for Computer related subjects.

I think(not sure):
If you dont want to use windows.h, you should forget about dlls.

Linux has .so extension for dynamic libraries.
May be these link can give you some information:
Writing Dlls for Linux Apps
Dynamically loaded libraries in Linux

I'll try to find more information about this.

Regards,
Paramesh.
__________________

Don't walk in front of me, I may not follow.
Don't walk behind me, I may not lead.
Just walk beside me and be my friend.
 
 

Recent GIDBlogMeeting the local Iraqis by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 06:34.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.