Thread: DLL Fundamentals :: MFC

  1. #1
    kuphryn
    Guest

    DLL Fundamentals :: MFC

    Hi.

    I am learning DLL creation and implemention from Programming Applications for Microsoft Windows by Jeffrey Richter. Richter demonstrations are straightforward and appear simple. However, I cannot implement a working at all using Visual C++ .NET.

    I tried using the DLL Wizard and hardcoding a .cpp and .h file. Neither method worked. I would like to create a simple dll with functions I can use in any C++ programs I work on including MFC. In fact, all my Windows program are MFC. Here is an example of the code.

    -----
    // myDLL.h

    #ifndef myDLL
    #define myDLL extern "C" __declspec(dllimport)
    #endif

    class myDLL MyClass
    {
    MyClass();
    void FunctionOne();
    int FunctionTwo();
    ~MyClass();
    -----

    -----
    // myDLL.cpp

    #define myDLL extern "C" __declspect(dllexport)
    #include "stdafx.h"
    #include "myDLL.h"

    MyClass::MyClass()
    {
    }
    ...
    -----

    The code above uses the exact sample algorithm Richter presents in his book. It is does not work. I would like a good solid working example of creating a dll that works in both MFC and non-MFC Windows programs.

    Thanks,
    Kuphryn

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Are you linking to the DLL's library as well as the .h and actual DLL? (which should be created when you create the DLL and is needed for needed for implicit or static linking)

    Otherwise try an explicit link with a DLL function

    int MyFuncName(HWND hWnd,char *sBuffer);
    Code:
    typedef int (WINAPI* TYPE_MyFunct)(HWND, char *);
    
    hDLLInst=LoadLibrary(DLL_PATH);
    if(hDLLInst!=NULL)
    {
         MyFunc = (TYPE_MyFunct) GetProcAddress(hDLLInst , "MyFuncName" );
         if(MyFunc==NULL)
         {
               //error
         }
    //use DLL
    FreeLibrary(hDLLInst);
    But I use WIN32 API with MSVC++ v6 no MFC, no C++ so may be some slight differences.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    C++ DLL's in a nutshell

    Few points...
    [list=1][*]Your Dll code is not exporting ...it is trying to import[*]If you use extern "C", you are losing all the namemangling that allows C++ to work.....therefore forget it if you are working with classes in C++ Dlls[*]Your class functions are private by default....therefore you wouldnt be able to call them anyway![/list=1]

    Ok......here's and example of how to export a class under VC++

    1. The Dll itself

    Code:
    //MyDll.h
    #include <iostream>
    using namespace std;
    
    #ifdef IMPORT_DLL
    #define DLL_LINK __declspec(dllimport)
    #else
    #define DLL_LINK __declspec(dllexport)
    #endif
    
    
    class DLL_LINK MyClass
    {
    public:
    	 void sing();
    };
    Code:
    //MyDll.cpp (short & sweet :))
    #include "MyDll.h"
    
    void MyClass::sing(){cout << "Hello Dll!!";}
    Now....create that project as a standard Dll prjoject.......In the output, you will get MyDll.lib and MyDll.dll.....now copy the dll, the MyDll.h and the lib to a new standard workspace and use the following code...

    2. The App

    Code:
    //CallMyDllApp.cpp
    #pragma comment(lib,"MyDll.lib")//quick way of including libs...
    #define IMPORT_DLL //Define this to allow the header to act as an import header
    #include "MyDll.h"//From the other project
    
    int main(void){
    
    	MyClass mc;
    	mc.sing();
    	return 0;
    }
    This is the way I do it.....works, but you can have your own little tricks to do things too.......it should give you an idea

  4. #4
    kuphryn
    Guest
    Okay. I just cannot get the compiler to compile the dll without errors.

    I have uploaded the entire dll project to my website. Please check it out and see if you can determine the error. I use the exact same technique Jeffrey Richter shows in his book. However, the compiler saying a .pch file cannot be found. Second, I do not understand why Visual C++ includes the stdafx.h file in all projects.

    http://www.dslextreme.com/users/kuph...e/FirstDLL.zip

    Please post if you find an unconditional working solution.

    Thanks,
    Kuphryn

  5. #5
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by kuphryn
    Okay. I just cannot get the compiler to compile the dll without errors.

    I have uploaded the entire dll project to my website. Please check it out and see if you can determine the error. I use the exact same technique Jeffrey Richter shows in his book. However, the compiler saying a .pch file cannot be found. Second, I do not understand why Visual C++ includes the stdafx.h file in all projects.

    http://www.dslextreme.com/users/kuph...e/FirstDLL.zip

    Please post if you find an unconditional working solution.

    Thanks,
    Kuphryn
    ::SIGH::

    Why dont you take a few minutes and read the example I posted?
    [list=1][*]#define FIRSTDLL extern "C" - NO! See above[*] __declspec(dllimport) - NO! See above[/list=1]

    Aslo your not actually trying to export anything in that code......you try define the FIRSTDLL and then simply dont use it

  6. #6
    kuphryn
    Guest
    How come you do not use extern "C?" Is there an advantage to not using it?

    I will try to implement it soon.

    Kuphryn

  7. #7
    kuphryn
    Guest
    Okay. I tried using your solution, but I keep seeing the error that a .pch file is missing.

    Kuphryn

  8. #8
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    When a C++ compiler exports a class it does it with type safety....and also allows stuff like operator overloading etc...To allow the linker to link properly and surely it needs to be able to differentiate between functions properly.......To remedy this, C++ introduced the idea of name mangling......

    This means the compiler translates the function definition into something more meaningfull ...IE before linking a function could be transformed into;

    Code:
    ??4foobar@@UEA@A
    Or something equally confusing......but from this, the linker knows what the exactly which the function is, what the function will return and what it expects as params....

    This stuff allows C++ to operate in all its glory, but extern "C" strips away all this name mangling and so stops your compiler and linker from doing all this stuff for you...

    All the extern "C" statement does is promises your compiler that the function lies outside of the module, and can be called with the C calling convention (push params onto stack....issue call statement.....pop params back off after ret).......therefore for what we want to do its not adequate!

    Stick with the standard __declspec(dllexport) in the class declaration

  9. #9
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by kuphryn
    Okay. I tried using your solution, but I keep seeing the error that a .pch file is missing.

    Kuphryn
    Just loaded it up again on VC++6...works ok

    A .pch file is just an precompiled intermediate file....

    Go to project settings....C++....category->precompiled headers and disable the option from there....then try

  10. #10
    kuphryn
    Guest
    Okay. Thanks.

    Everything works. Well, it compiled okay. Hey, that is a huge step!

    Kuphryn

  11. #11
    kuphryn
    Guest
    One more questions.

    You used this:

    -----
    #if defined(FIRSTDLL_DLL)
    # define FIRSTDLL extern "C" __declspec(dllexport)
    #else
    # define FIRSTDLL extern "C" __declspec(dllimport)
    #endif
    -----

    I am able to compiler the DLL using this code too.

    -----
    // FirstDLL.h
    #ifndef FIRSTDLL_H
    #define FIRSTDLL_H

    #define IMPORT __declspec(dllimport)
    #define EXPORT __declspec(dllexport)

    #ifdef __cplusplus
    extern "C"
    {
    #endif

    class EXPORT myClass
    {
    ...
    };

    #ifdef __cplusplus
    }
    #endif

    #endif
    -----

    Is there an advantage one declaration has over the other?

    Thanks,
    Kuphryn

  12. #12
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    I was suprised that that worked......but I looked at the produced lib under a hex editor and noticed that it was still using name mangling.....

    According to my MSDN

    Use of static and extern

    Construct - Can extern be Used?

    ...

    Class member functions - No
    Class member data - No
    So my guess is that the compiler is simply ignoring you when you try enclose the class in an extern "C" block

    If your using C++ in the dlls....and your using C++ in your project (Hell your exporting classes...so you dont have much option)!...and you dont expect to have to link to other compilers apart from the one you initially used....then jusy exporting the class declaration with __declspec(dllexport) should do you fine

  13. #13
    kuphryn
    Guest
    Okay. Thanks.

    Kuphryn

  14. #14
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Fordy:

    I noticed in your example you link to the lib file and then include the header as "imported" If you took out the DLL stuff wouldn't it be exactly the same? I mean, if you are using DLL's shouldn't you be able to leave out the lib? I thought the old lib's were statically linked and DLL's could fully replace them if needed. A little confused why you used both there.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  15. #15
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    To use a DLL implicitly you need to link to both a DLL's header and library. The library is created when the DLL is built.

    If linking explicitly, this lib is not needed as the DLL is dynamicly loaded at run time, though sometimes a .def file is needed to link explicitly without function names being 'mangled' (and so failing GetProcAddress() ).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. non-MFC DLL with MFC app question.
    By Kempelen in forum Windows Programming
    Replies: 10
    Last Post: 08-20-2008, 07:11 AM
  2. Mfc Dll
    By xlnk in forum Windows Programming
    Replies: 2
    Last Post: 06-10-2003, 06:20 PM
  3. WIndows programming?
    By hostensteffa in forum Windows Programming
    Replies: 7
    Last Post: 06-07-2002, 08:52 PM
  4. Release MFC Programs & Dynamic MFC DLL :: MFC
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 05-18-2002, 06:42 PM
  5. MFC: Multi-threaded DLL Errors & Related Syntax :: C++
    By kuphryn in forum C++ Programming
    Replies: 3
    Last Post: 02-13-2002, 09:02 AM