Thread: __declspec(dllexport) and __stdcall

  1. #1
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297

    __declspec(dllexport) and __stdcall

    This is probably just a massive brain fart but if you declare a function with __declspec(dllexport) is it automatically __stdcall? does it not need to be explicit? trying them both together doesn't compile of course.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  2. #2
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    I doubt it......C Compilers normally switch to __cdecl until told otherwise.....

    __declspec(dllexport) is just a special (and more efficient) method of exporting symbols

  3. #3
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    Well that's what I'm asking then, are you able to export a __stdcall or other types with a __declspec.

    for instance:

    __declspec(dllexport) __stdcall int Func(int blah);

    //this doesn't compile of course but it's the idea I'm going for.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  4. #4
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    Have you tried -

    __declspec (dllexport) int __stdcall Func(int blah);
    Joe

  5. #5
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Yeah...just tried it....

    Code:
    //The dll
    #include <windows.h>
    #include <iostream>
    
    
    void __declspec(dllexport) CallC(char* szText){
    
    	std::cout << szText << std::endl;
    	
    }
    
    void __declspec(dllexport) __stdcall CallStd(char* szText){
    
    	std::cout << szText << std::endl;
    	
    }
    Code:
    #include <windows.h>
    #pragma comment(lib,"TestDll.lib")
    
    void __declspec(dllimport) CallC(char* szText);
    
    void __declspec(dllimport) __stdcall CallStd(char* szText);
    
    int main()
    {
    
    	CallC("Hello World");
    
    	CallStd("Hello World");
       
    
    	return 0;
    }
    The disassembly revealed

    11: CallC("Hello World");
    00401028 mov esi,esp
    0040102A push offset string "Hello World" (0041f01c)
    0040102F call dword ptr [__imp_?CallC@@YAXPAD@Z (00424290)]
    00401035 add esp,4
    00401038 cmp esi,esp
    0040103A call __chkesp (00401090)
    12:
    13: CallStd("Hello World");
    0040103F mov esi,esp
    00401041 push offset string "Hello World" (0041f01c)
    00401046 call dword ptr [__imp_?CallStd@@YGXPAD@Z (00424294)]
    0040104C cmp esi,esp
    0040104E call __chkesp (00401090)
    The normal declaration without __stdcall restored the stack - so its __cdecl.....and where I explicitly said __stdcall it didnt

  6. #6
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    Joe, you're so right. dang I'm an idiot. thanks.

    further.... can you do a member function?

    __declspec(dllexport) int __thiscall Func();
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  7. #7
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by FillYourBrain
    Well that's what I'm asking then, are you able to export a __stdcall or other types with a __declspec.

    for instance:

    __declspec(dllexport) __stdcall int Func(int blah);

    //this doesn't compile of course but it's the idea I'm going for.


    Oops...Your declarations are wrong..see my example

  8. #8
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by FillYourBrain
    Joe, you're so right. dang I'm an idiot. thanks.

    further.... can you do a member function?

    __declspec(dllexport) int __thiscall Func();
    Hmm....never tried.....you can export a whole class though

  9. #9
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    The only reason I'm doing all of this is because the only thing I ever usually export is a _cdecl function. I know that you can export classes and variables as well. Have you guys had any real experience with exporting classes? I've heard much about how horribly this has been implemented.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  10. #10
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by FillYourBrain
    The only reason I'm doing all of this is because the only thing I ever usually export is a _cdecl function. I know that you can export classes and variables as well. Have you guys had any real experience with exporting classes? I've heard much about how horribly this has been implemented.
    Yes...you just need the class declaration in the module you which to import to....often you just reuse the header

    Code:
    //dll
    #include <windows.h>
    #include <iostream>
    
    
     class __declspec(dllexport) foobar{
    public:
    	foobar();
    	~foobar();
    	void Sing();
    };
    
    foobar::foobar(){
    	std::cout << "Constructor" << std::endl;
    }
    
    foobar::~foobar(){
    	std::cout << "Destructor" << std::endl;
    }
    	
    void foobar::Sing(){
    	std::cout << "Lala" << std::endl;
    }
    Code:
    #include <windows.h>
    #pragma comment(lib,"TestDll.lib")
    
    class __declspec(dllimport) foobar{
    public:
    	foobar();
    	~foobar();
    	void Sing();
    };
    
    
    int main()
    {
    
    	foobar f;
    
    	f.Sing();
       
    
    	return 0;
    }

  11. #11
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    Fordy, that's a static linking example... How would you dynamically link. I assume ::GetProcAddress() is not very useful for non functions.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  12. #12
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by FillYourBrain
    Fordy, that's a static linking example... How would you dynamically link. I assume ::GetProcAddress() is not very useful for non functions.
    Hmm...not sure.....normally, in examples where they want to export class methods I have seen people wrap them in a func....might very well be a method, but I cant think of one right now...

  13. #13
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    If not, I can't really see doing it. Creating COM-like interfaces and passing them over seems like a better method (that's what I've always done).
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  14. #14
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    although, there may be a way of "re-assembling" a class by exporting the methods as I mentioned above. Then you could fill in a class to derive from with virtual function pointers from the dll. That would be very strange but it seems like it might work.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  15. #15
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    See www.bcbdev.com/articles/vcdll2.htm

    This excellent. Ignore references to VCL v BCB, it's just talking about exporting objects from a DLL & how do it from the ground up.

    If you need inheritence, let me know.
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

Popular pages Recent additions subscribe to a feed