Thread: Help with simple console to dll code

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    That is unnecessarily complex. Dynamic dll loading and function calling is not needed for this and can cause headaches. Plus "C" style functions are not required at all, unless this dll is to be used from C, but this is C++, so...
    In your .def file, it should look something like this:

    Code:
    ; Stuff.def : Declares the module parameters for the DLL.
    
    LIBRARY      "Your Library"
    
    EXPORTS
    	; Explicit exports can go here, examples:
    	foo
    	foo2
    In that EXPORTS section, put all the names of the functions you want to export. See example above.
    Then of course, you have those functions declared somewhere in a header:

    Code:
    void foo();
    void foo2();
    So then you simply add a reference to your dll:
    http://i201.photobucket.com/albums/a...pendencies.jpg
    (Example above: adds a reference to library Stuff from program Help)

    Then simply call the functions as normal (including the appropriate header, of course)!
    Code:
    int main()
    {
    	foo();
    	foo2();
    }
    Last edited by Elysia; 01-25-2008 at 06:39 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #17
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Code:
    ; Stuff.def : Declares the module parameters for the DLL.
    
    LIBRARY      "Your Library"
    
    EXPORTS
    	; Explicit exports can go here, examples:
    	foo
    	foo2
    I have a few questions.

    How do you plan on making the above def work without any ordinals?

    Also, assume we're using MS Visual C++ . How would you handle a decorated name change if you install a newer version of a MS compiler or possibly a service pack? MS is free to change the decoration anytime they desire.

    Now let us assume this is a commercial DLL. The decorated names are constructed using the exported symbol name, parameter list and return type. How would you handle a change in parameters and/or return type?

    Finally, unless you plan on writing your DLL in pure C++, the following makes absolutely no sense. Please elaborate.

    Plus "C" style functions are not required at all, unless this dll is to be used from C, but this is C++,
    Last edited by BobS0327; 01-25-2008 at 10:17 PM.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    So far as I'm concerned, whatever the exported name will be, the same exported name will be used when calling the functions, so it should work with just a recompile even if they change the decorated name. Else they would break everything in the language, wouldn't they?
    Now see, your example sacrifices C++ functions with C instead. In C++, it's possible to export overloaded functions. It's not in C. So when using static linking and C++, why take advantage of those features? There's absolutely no need to export it as a C function.
    And if you're confused about that... Well, either you write your apps in C or C++. No need to mix the two unless there's some complicated project or things. I don't think a simple newbie programmer has to worry about export C-style and mixing C/C++. Myself I only write C++, so there's absolutely no need for C-style function exports.

    Static linking is much easier than dynamic linking.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    So far as I'm concerned, whatever the exported name will be, the same exported name will be used when calling the functions, so it should work with just a recompile even if they change the decorated name. Else they would break everything in the language, wouldn't they?
    You really don't have any idea what a decorated name is. The users do not change the decorated name. It's a C++ internally generated name to represent operator overloads and to distinguish between overloaded functions. The user must discover what these names are in order to put them into the def file. Also, it's really obvious that you don't understand decorated names because you ignored my other questions.

    That leads me to another question. Since your a C++ person and you suggest this means of using a DLL. How would you instruct the OP to determine the decorated name of an overloaded function? I'm sure the OP will need this info if he wants to write a C++ DLL.

    Also, your def file is wrong whether you use in in a C or C++ envronment. It'll do nothing more than break the application using the DLL. The def file needs ordinals to represent the position of the function address pointer in the Export Address Table. Without ordinals, the linker will generate different ordinals and your app will crash.

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I have a big idea what it is and it is in no way wrong.
    It works as expected, since I have long used many dlls with .def files this way.
    Whether that just works within Visual Studio or not, I don't know. But in Visual Studio it works. The linker will find the correct function and export it fine. If it doesn't work in other compilers, then do elaborate on the subject.
    A decorated name, I do know what it is. Name mangling. But the thing is that the compiler will automatically generate the same name from the dll function as the generated name when calling the function from an exe outside the dll, so whatever the compiler chooses to mangle the name as, it will still call the function correctly.

    Try it. It works.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #21
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I've put together a pure C++ dll which requires a DEF file as listed below. It does the same exact processing as the previous C sample. Thus, the OP can test both the C and C++ versions. It is highly recommended that the OP overload one of the functions in the C++ version. Also, through experimentation, you can validate the statements made in this thread.

    Code:
    LIBRARY myclass.dll
    EXPORTS
    	CreateMyClass               @2 PRIVATE         
    	DeleteMyClass               @3 PRIVATE          
    	GetClassMethod              @4 PRIVATE
    Code:
    // File: myclass.h
    
    #ifndef __MYDYNCLASS_H
    #define __MYDYNCLASS_H
    
    #include <windows.h>
    
    #ifdef _DLL 
    #define _DYNAMICLINK __declspec( dllexport)
    #else
    #define _DYNAMICLINK __declspec( dllimport)
    #endif
    
    class _DYNAMICLINK MyClassinDLL
    { 
        public:
        MyClassinDLL ();
        virtual ~MyClassinDLL();
        void MyFunction(char * pIn, unsigned char * pOut );
    };
    
    typedef void ( MyClassinDLL::*PMYCLASSSYAHELLOMETHOD)(char * pIn,  unsigned char * pOut);
    
    #ifndef _DLL
    typedef MyClassinDLL* ( *PFNINITIALIZEMYDLLCLASS )();
    #else
    _DYNAMICLINK MyClassinDLL* CreateMyClass() 
    { 
        return (new MyClassinDLL());
    }
    #endif
    
    #ifndef _DLL
    typedef void (*PFNDELETEMYDLLCLASS)( MyClassinDLL*);
    #else
    _DYNAMICLINK void DeleteMyClass (MyClassinDLL* pObj) 
    { 
        delete pObj;
    }
    #endif
    
    #ifndef _DLL
    typedef PMYCLASSSYAHELLOMETHOD (PFNGETCLASSMETHOD)(char * pIn,  unsigned char * pOut);
    #else
    _DYNAMICLINK PMYCLASSSYAHELLOMETHOD GetClassMethod (char * pIn,  unsigned char * pOut) 
    { 
     
        return (&MyClassinDLL::MyFunction);
    }
    #endif
    #endif
    Code:
    // File: myclass.cpp
    // Compile: cl.exe /LD /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_DLL" /D "_WINDLL" /FD /EHsc /MTd  /W3 myclass.cpp /link /DLL /DEF:"myclass.def" 
    #include <windows.h>
    #include <iostream>
    #include "myclass.h"
    
    MyClassinDLL::MyClassinDLL ()
    {
        std::cout << "Class Created" << std::endl;
    }
    
    MyClassinDLL::~MyClassinDLL()
    {
        std::cout << "Class Deleted" << std::endl;
    }
    
    void    MyClassinDLL::MyFunction(char *pIn, unsigned char * pOut) 
    {
        for(int iIndex = 0; iIndex < strlen(pIn); iIndex++)
        {
            pOut[iIndex] = pIn[iIndex];
            pOut[iIndex]++;
        }
    }
    Code:
    // File: myapp.cpp
    // Compile:  cl.exe /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /EHsc /MLd  myapp.cpp
    #include <windows.h>
    #include <iostream>
    #include "myclass.h"
    
    int main( void )
    {
        int iIndex;
        char Input[] = {"Testing"};
        unsigned char Output[128] = {0};
        PFNINITIALIZEMYDLLCLASS pfnInitializeMyClass = NULL;
        PFNDELETEMYDLLCLASS pfnDeleteMyClass = NULL;
        PFNGETCLASSMETHOD *pfnGetClassMethod = NULL;
        PMYCLASSSYAHELLOMETHOD  pfnMyFunction = NULL;
        MyClassinDLL* pMyClass = NULL;
    
        HMODULE hDll = (HMODULE) INVALID_HANDLE_VALUE;
        hDll = LoadLibrary( "myclass.dll" );
        if( INVALID_HANDLE_VALUE == hDll )
        {
            std::cout << "LoadLibrary failed" << std::endl;
            returnf -1;
        }
        pfnInitializeMyClass = ( PFNINITIALIZEMYDLLCLASS ) GetProcAddress( hDll, "CreateMyClass" );
        pfnDeleteMyClass = ( PFNDELETEMYDLLCLASS ) GetProcAddress( hDll, "DeleteMyClass" );
        pfnGetClassMethod =( PFNGETCLASSMETHOD * )GetProcAddress( hDll, "GetClassMethod" );
    	pMyClass = ( pfnInitializeMyClass ) ();
        pfnMyFunction =( pfnGetClassMethod(Input, Output ));
        ( pMyClass->*pfnMyFunction )(Input, Output);
        for(iIndex = 0; iIndex < strlen(Input); iIndex++)
            std::cout << Input[iIndex] << "  " << Output[iIndex] << std::endl;
        ( pfnDeleteMyClass( pMyClass ));
        FreeLibrary ( hDll );
        return 0;
    }

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You really should separate these names:
    PMYCLASSSYAHELLOMETHOD
    into something more readable such as
    PMY_CLASS_SYA_HELLO_METHOD
    or
    PMyClassSyaHelloMethod

    And this example should work even without the .def file since you're exporting through __declspec which is Microsoft specific.
    And you are still doing the dynamic loading method, even though you are linking statically.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #23
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Code:
    And this example should work even without the .def file since you're exporting through __declspec which is Microsoft specific.
    And you are still doing the dynamic loading method, even though you are linking statically.
    The answer's staring right at you. The DLL is written using C++ classes. But we are still using a C interface which now reqires a DEF file. Also, the DLL functions are not to be listed in the import lib which requires a DEF file to accomplish.

  9. #24
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I have no idea why you're making this so complicated.
    Either you put the function names in the .def files (and you don't even have to specify anything other than the function name) OR you use __declspec(dllexport/dllimport).
    You then add a reference to the project OR link against the .lib file to make static linkage.
    If using static linkage, you only need to call the functions and not retrieve their addresses first. The library is statically loaded when the application starts.
    IF you don't do the above, then you must do dynamic linking which is what you do.

    I have done a lot of dlls too. On Windows. With Visual Studio. And it works just fine!
    When exporting classes, you can just use __declspec(dllexport/dllimport) and the entire class be exported and then imported easily.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #25
    Registered User
    Join Date
    Jan 2008
    Posts
    10
    You all rock! Thank you SO, SO much!

  11. #26
    Registered User
    Join Date
    Jan 2008
    Posts
    10

    Help again

    Thanks you all for your help. Using your help I thought I got my dll to work but I have a bug someone might be able to help with with.

    Code:
    #include "stdafx.h"
    #include <stdio.h>			// for namespace
    #include <valarray>			// for Xor 
    #include <string>
    
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        return TRUE;
    }
    
    	char outvalue[] = "";
    	unsigned int v=0;
    	unsigned int vlen=0;
    	char out [5] = "";
    
    
    __declspec(dllexport) LPCTSTR ecc(LPCTSTR invalue)
    {
    
    
    
    // Setup Values of Variables 
    	vlen = strlen(invalue);
    	
    	outvalue[0] = invalue[0];
    														//cout <<  invalue << endl;
    
    	
    // Loop
        for(v;v<vlen-1;v++)
        {
    														//cout<<  outvalue [0];
    														//cout<< invalue[v+1];
    	outvalue [0] ^=  invalue[v+1];   
    														//cout<< outvalue [0] << endl ;
        }
    
    
    
    
    
    	sprintf_s(out, "%X", outvalue[0]);
    	
    	
    	return out;
    	
    }
    The first time it runs, it returns the correct value I need but if I run the dll again it incorrect (acually I've noticed that it returns a 41 on the second time).

    Anyone have any ideas? Am I using sprintf_s correctly?

  12. #27
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    why not to declare variables locally in your function?

    And I do not understand:

    char outvalue[] = "";

    If you need only 1 char declare it as
    char outvalue=0;

    and use it as so...
    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

  13. #28
    Registered User
    Join Date
    Jan 2008
    Posts
    10
    how do you do that?

  14. #29
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Exporting classes in DLL's is a snap as Elysia has said. I've never seen code where both the .DEF file and the __declspec were used. I was always under the impression it was one or the other but not both. Normally I just have the header, the DLL, and link with the export lib and everything works just fine.

    And no offense intended BobS0327 but the code you posted is quite complex for a very simple task. Creating DLLs in Visual Studio is very simple and straightforward.

  15. #30
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by Bubba View Post
    I was always under the impression it was one or the other but not both.
    A third method btw is the use of the /EXPORT linker switch

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating a simple DLL
    By Dark_Phoenix in forum C++ Programming
    Replies: 8
    Last Post: 03-07-2009, 09:41 PM
  2. Problems with a simple console game
    By DZeek in forum C++ Programming
    Replies: 9
    Last Post: 03-06-2005, 02:02 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Creating a Simple DLL in C
    By Ultima4701 in forum C Programming
    Replies: 2
    Last Post: 11-23-2002, 01:01 PM
  5. Replies: 1
    Last Post: 01-29-2002, 02:49 AM