Thread: creating a simple DLL

  1. #1
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174

    creating a simple DLL

    I created my first (VERY) simple DLL that contains 3 functions... add, subtract and multiply. I then created a program to test the DLL. Problem is the add function works fine but it seems like the calls to the other two are failing and I can't quite figure out why...

    the DLL is
    dllmain.h
    Code:
    #ifndef DLLMAIN_H_INCLUDED
    #define DLLMAIN_H_INCLUDED
     
    #include <windows.h>
    #define DLL_EXPORT __declspec(dllexport)
     
    #ifdef __cplusplus
    extern "C"
    {
    #endif
     
    int DLL_EXPORT subtract(int, int);
    int DLL_EXPORT add(int, int);
    int DLL_EXPORT multiply(int, int);
     
    #ifdef __cplusplus
    }
    #endif
     
    #endif // DLLMAIN_H_INCLUDED
    and dllmain.cpp
    Code:
    #include "dllmain.h"
     
    int DLL_EXPORT subtract(int a, int b) { return a - b; }
    int DLL_EXPORT add(int a, int b) { return a + b; }
    int DLL_EXPORT multiply(int a, int b) { return a * b; }
     
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        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;
        }
        return TRUE; // successful
    }
    and the test file is main.cpp
    Code:
    #include <windows.h>
    #include <iostream>
     
    typedef int (*FunctionPtr)(int, int); // definition of the function from the DLL
     
    int main()
    {
        HINSTANCE    hinstDLL = NULL;     // HINSTANCE of the DLL to load
        FunctionPtr  FuncToCall = NULL;   // address of the function to call
     
        // load the DLL containing the function definitions
        hinstDLL = LoadLibrary("DLL/bin/Release/test.dll");
     
        // if the DLL loaded OK then get the function address
        if(hinstDLL != NULL)
        {
            FuncToCall = (FunctionPtr)GetProcAddress(hinstDLL, "multiply");
        }
        else
        {
            std::cout<<"DLL failed to load!\n";
            return 0;
        }
     
        // if it is a good address the call the function
        if(FuncToCall != NULL)
        {
            std::cout<<FuncToCall(8, 5) <<"\n";
        }
        else
        {
            std::cout<<"Function address is NULL\n";
        }
     
        // free the DLL and exit
        FreeLibrary(hinstDLL);
        return 0;
    }
    the functins are identical except for the operator being used and I am not sure what else could cause the problem... any ideas?
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  2. #2
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    ok, nevermind... i had an IDE setting wrong. It's working now.
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You need extern "C" in your dllmain.cpp file as well as the header. I'm kind of surprised it works without it.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    I thought so... I was going by both MSDN's example, which I though was a bit hard to follow, and this one, which shows the extern "C" only in the .h file. I went back and added it to the .cpp file as well and everything still works fine, althouh I do not understand why it is needed in the .cpp file....
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  5. #5
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    I believe it is because the compiler may "mangle" the name of the function to handle function overloading.
    Woop?

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by brewbuck View Post
    You need extern "C" in your dllmain.cpp file as well as the header. I'm kind of surprised it works without it.
    if I remember correct enough to have the first declaration of the function with the
    extern "C" keyword to make all folow-up declaration/definitions extern "C" as well

    so - if cpp-file includes the h-file - no need to use extern "C" specification in it
    if the include is missing - yes you need to add it as well because when compiling this file the definition of the function will be its first declaration
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    OK, I see... That makes sense. So as long as all the definitions have a matching declaration in the .h file then extern c is not needed in the cpp file.

    Now, would the same hold true for class or struct definitions? Or even typedef's?
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I'm not sure about structs, but I wouldn't think you'd even be able to extern "C" a class, since C doesn't have classes. And typedefs have to be resolved at compile-time, so I think that maybe you wouldn't need to extern "C" them. You'd have to do some experimenting.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    Why not just use the normal import export style. to avoid the Loading/Unloading of the DLL manually?
    Code:
    #ifdef EXPORT_SYMBOLS
    #define MYPROJECT_API __declspec(dllexport)
    #else
    #define MYPROJECT_API __declspec(dllimport)
    #endif

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Calling a DLL
    By jamez05 in forum C++ Programming
    Replies: 1
    Last Post: 01-05-2006, 11:13 AM
  2. dll communicating between each other
    By cloudy in forum C++ Programming
    Replies: 5
    Last Post: 06-17-2005, 02:20 AM
  3. How make dll in in simple c\c++?
    By awm9 in forum C++ Programming
    Replies: 2
    Last Post: 07-09-2004, 02:31 PM
  4. Using class with DLL
    By greg2 in forum C++ Programming
    Replies: 2
    Last Post: 09-12-2003, 05:24 AM
  5. Creating object of type HWND from a dll
    By Unregistered in forum Windows Programming
    Replies: 2
    Last Post: 03-13-2002, 12:40 AM