• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            concentrate on c/c++ related technology

            plan,refactor,daily-build, self-discipline,

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              37 Posts :: 1 Stories :: 12 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(9)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            這回貼上來自codeguru上面的一篇討論,感覺很舒服:
               

            I’ve created a very simple Win32 DLL. It only has one exported function called “Test” whose declaration looks like this:-

            #ifdef MYDLL_EXPORTS
            #define MYDLL_API __declspec(dllexport)
            #else
            #define MYDLL_API __declspec(dllimport)
            #endif


            MYDLL_API HRESULT Test(void);
            Then in the source file:-

            MYDLL_API HRESULT Test(void)
            {
            return (HRESULT) 66;
            }


            Now in my executable, I’ve done this:-

            static HMODULE hDLL;
            typedef HRESULT (STDAPICALLTYPE * LPFNTEST) (void);
            LPFNTEST _pfnTest;

            Then I load the DLL:-

            hDLL = LoadLibrary("MyDLL.dll");

            All the above works fine and hDLL gets a non-NULL value . Now I come to obtain the proc address for function “Test”:-

            _pfnTest = (LPFNTEST)::GetProcAddress(hDLL, "Test");
            but _pfnTest ends up as NULL and GetLastError() returns 127 (ERROR_PROC_NOT_FOUND). What have I done wrong?? I haven't implemented any code yet in DllMain(). For example, I haven't initialised anything. Should I have done?


            Siddhartha

            February 20th, 2006, 11:18 AM

            but _pfnTest ends up as NULL and GetLastError() returns 127 (ERROR_PROC_NOT_FOUND). What have I done wrong?? You have not accounted for the name decoration that the VC++ Compiler has subjected your DLL's Exported Functions to.

            To know exactly what it has done, open the DLL in Dependency Walker and observe exported function names...

            www.dependencywalker.com (http://www.dependencywalker.com) (for latest version)
            You either need to GetProcAddress of the functions using their decorated names, or better - create entries in your DLL Project's DEF File that define the names of the exported functions the way you would like to see them as.

            Something like this -
            LIBRARY "MYDLL"

            EXPORTS
            Test PRIVATE


            Bornish

            February 20th, 2006, 11:18 AM

            Your function is exported using the C++ decorated name. Use extern "C" before the function prototype, or use a *.def file in your project containing:EXPORTS
            TestTo know for sure that your function is exported with an undecorated name, use Dependency Viewer to list its exports.

            Note: I've noticed another potential problem, which will not affect this test function since has no parameters, but your dll declares the function as __cdecl (depending on your project's default settings), and the exe tries to use it with STDAPICALLTYPE which I assume stands for __stdcall calling convention.

            Regards,


            John E

            February 20th, 2006, 11:31 AM

            Thanks guys. It's ages since I wrote a DLL. It's all starting to come back to me now!! :wave:


            John E

            February 23rd, 2006, 04:51 PM

            Hmmm.... this still isn't quite right. According to this MSDN article (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/msmod_20.asp) the use of dllimport and dllexport should eliminate the need to specify exported functions in a module definition file (.DEF)

            However, in my case, that's not working. I'm finding that I still need to list the functions as EXPORTS in a .DEF file - even though I'm correctly defining __declspec(dllimport) and __declspec(dllexport). Any ideas about what I might be doing wrong?


            Paul McKenzie

            February 23rd, 2006, 05:06 PM

            Hmmm.... this still isn't quite right. According to this MSDN article (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/msmod_20.asp) the use of dllimport and dllexport should eliminate the need to specify exported functions in a module definition file (.DEF)Only if you are linking with the export library, in other words, you're using Visual C++ and you add the .lib to your project.

            If you're using LoadLibrary() and GetProcAddress(), there is no .lib file to help the linker resolve the name. You must either use the *exact* name you see in the exported function list when you ran Dependency Walker, or you use a def file and rebuild your DLL to get a totally "clean" function name.

            Regards,

            Paul McKenzie


            Bornish

            February 23rd, 2006, 05:07 PM

            If you use __declspec(dllexport) you don't need the def file.
            In fact, with only a def file you might get into an ambiguous name situation (like it happen to me before), when a class declared a method with the same name of the global exported function. The solution was to use __declspec(dllexport) for the global function.
            The problem we suggested you might have was that your function was exported with a C++ decorated name. Thus, you need to use extern "C" before __declspec(dllexport).
            Got to go now... :)
            Regards,


            John E

            February 23rd, 2006, 05:22 PM

            Only if you are linking with the export library, in other words, you're using Visual C++ and you add the .lib to your project.You mean if I link statically, rather than dynamically?

            Surely if I link statically, there's no need to mess about with dllimport and dllexport at all??


            VladimirF

            February 23rd, 2006, 05:28 PM

            Paul wasn't talking about static link, he compared dynamic linking with on-demand GetProcAddress() call.


            kirants

            February 23rd, 2006, 05:36 PM

            Hmmm.... this still isn't quite right. According to this MSDN article (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/msmod_20.asp) the use of dllimport and dllexport should eliminate the need to specify exported functions in a module definition file (.DEF)

            However, in my case, that's not working.

            I don't think that is the case. It is not working because you are doing a GetProcAddress with non-mangled name while using dllexport without using a def file causes name mangling and hence the failure.

            The reason it works when you add the .def file with the names is because you are putting the name in unmangled form in it and that is what you are using in GetProcAddress.

            So, summary si this:
            if you use dllexport approach without def file, please understand that the Visual C++ compiler mangles the name and this is the form in which your function will be exported. For e.g. your Test function will be exported as , ?Test@XWZ or something of that form. So, if you do a GetProcAddress, make sure you use "?Test@XWZ" and not "Test".
            If you use dllexport, but also supply a .def file with the undeclared names, the linker is gonna put that in the dll export section. So, you can now use GetProcAddress(hMod,"Test")
            If you do use .def file, there is no need to use dllexport directive
            If you do not want to use .def file and still want to use dllexport directive, wrap those functions with

            extern "C"
            {

            }


            kirants

            February 23rd, 2006, 05:38 PM

            You mean if I link statically, rather than dynamically?

            A dll is always dynamically linked. What Paul was referring to was implicit linking versus explicit linking via LoadLibrary/GetprocAddress


            John E

            February 23rd, 2006, 05:48 PM

            Thanks for the help. I did realise that the problem was because of decorated names. What I didn't realise was that I had to link to the lib if I used __declspec(dllexport).... I've managed to get it to work now, without the DEF file :wave:


            kirants

            February 23rd, 2006, 05:52 PM

            What I didn't realise was that I had to link to the lib if I used __declspec(dllexport)
            No. using dllexport does not mean you have to link to the .lib file.

            Whether you use dllexport or def file, you will always be able to use LoadLibrary/GetProcAddress approach , provided you pass the right export name to GetProcAddress


            John E

            February 23rd, 2006, 05:55 PM

            Oops... one other thing, just before I shoot myself in the foot...!

            Ultimately, this DLL will be going to someone who'll be calling it from Visual Basic .NET. This means that my lib file would be useless to them. Therefore, I guess I'm better off sticking to the .DEF approach on this occasion because I don't really want the names to be mangled.


            MikeAThon

            February 23rd, 2006, 11:59 PM

            A dll is always dynamically linked. What Paul was referring to was implicit linking versus explicit linking via LoadLibrary/GetprocAddress
            I think that Microsoft refers to these as "run-time dynamic linking" vs. "load-time dynamic linking". See http://msdn.microsoft.com/library/en-us/dllproc/base/using_dynamic_link_libraries.asp

            Mike


            kirants

            February 24th, 2006, 12:29 AM

            Interesting, Mike.. ... Microsoft seems to be using different terms for the same :)

            For e.g. see here
            http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_core_determine_which_linking_method_to_use.asp


            MikeAThon

            February 24th, 2006, 01:28 AM

            You're right: that is the same thing, and Microsoft is using different terminology for it.

            Mike


            gopal.srini

            February 24th, 2006, 02:49 AM

            Hi

            Continuing with this topic, could any one please tell me how to call a method from ddao35.dll, say - OpenDatabase whose return type is class- CdbDatabase - using __declspec( dllexport ), they have exported this function available in dbdao.h file

            I tried the follwoing but in vain

            typedef UINT (CALLBACK* LPFNDLLFUNC1)(LPCTSTR,BOOL,BOOL,LPCTSTR);
            LPFNDLLFUNC1 lpfnDllFunc1;
            char *get_ver = "?OpenDatabase@CdbDBEngine@@QAE?
            AVCdbDatabase@@PBDHH0@Z";

            if(hDLL)
            {
            lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,"?OpenDatabase@CdbDBEngine@@QAE?AVCdbDatabase@@PBDHH0@Z");


            if (!lpfnDllFunc1)
            {
            // handle the error
            FreeLibrary(hDLL);
            return 0;
            }
            else
            {
            lpfnDllFunc1("TestDB.mdb",0L,FALSE,NULL);
            printf("success");

            }

            I am getting unhandled exception in my.exe(ddao35.dll) 0xc0000005 Access violation

            Any help?

            Regards
            Gopal


            kirants

            February 24th, 2006, 03:40 AM

            gopal.srini, please start a new thread, since this seems to be a different problem and unrelated to the original question


            gopal.srini

            February 24th, 2006, 04:09 AM

            ok..sorry..

            Thanks
            Gopal


            wshcdr

            February 24th, 2006, 01:09 PM

            To use LoadLibrary(...),GetProcAddr(...) ,you must write a DEF file,


            Bornish

            February 25th, 2006, 09:56 AM

            To use LoadLibrary(...),GetProcAddr(...) ,you must write a DEF file, :eek: This is somehow correct, if one needs undecorated names to be exported.
            I thought using __declspec(dllexport) can eliminate the need of a *.def file. :blush:
            I've tried exporting a function Test from a DLL that doesn't make use of a def file, so I've wrote this:extern "C" __declspec(dllexport) int __stdcall Test(int x) {
            return ++x;
            }The result was an export named _Test@4 (C++ decorated), thus extern "C" having no effect. I've tried several other variations... even using the obselete keyword _export in a *.c file instead of a *.cpp file. Still didn't find a way to export my function as Test without using a def file. It seems to be the only way to define alias names when exporting functions or to export only by ordinal (NONAME)... else you'll get the C++ decorated name _Test@4.
            Conclusion:
            If you don't care less about the name used in GetProcAddress, then you don't need a def file... else, use a def and keep your _declspec(dllexport) to avoid ambiguities. An article from MSDN recomends writing in a def file both the alias name and the decorated name to avoid ambiguities:EXPORTS
            Test = _Test@4This way, when another namespace or class defines a function Test, the linker won't have a dilemma in choosing the function to export.
            Best regards,


            John E

            February 25th, 2006, 10:21 AM

            You've pretty much confirmed what I found myself. The only way to guarantee that the names don't get decorated is to put them in a .DEF file.

            If you go the __declspec(dllexport) route - together with __declspec(dllimport) - then, providing you use Paul's suggestion of linking to the DLL's associated lib file, you can call the functions as though they weren't decorated - but in fact, they still are.

            I assume that what the lib must do is simply to translate calls to each function's undecorated name into the corresponding call with the decorated name.

             

             

             

            posted on 2008-04-02 16:29 jolley 閱讀(482) 評論(0)  編輯 收藏 引用
            97精品国产97久久久久久免费 | 热RE99久久精品国产66热| 欧美精品九九99久久在观看| 欧美久久久久久| 久久久久99精品成人片试看| 狠狠色丁香久久综合五月| 国产成人精品久久综合| 色播久久人人爽人人爽人人片aV| 久久久久久久精品成人热色戒| 97久久精品无码一区二区天美| 777久久精品一区二区三区无码| 亚洲国产成人久久综合野外| 99久久免费国产精品热| 日韩AV毛片精品久久久| 久久久老熟女一区二区三区| 久久久久国产精品三级网| 久久久久人妻精品一区二区三区| 免费精品久久久久久中文字幕| 久久综合给合久久狠狠狠97色69 | 久久午夜羞羞影院免费观看| 国产成人精品综合久久久| 无码人妻久久一区二区三区| 久久综合久久伊人| 曰曰摸天天摸人人看久久久| 久久精品欧美日韩精品| 精品久久久久久国产| 伊人久久大香线蕉成人| 久久久久久亚洲精品不卡| 久久99精品综合国产首页| 久久精品亚洲一区二区三区浴池| 欧美亚洲国产精品久久| 伊人伊成久久人综合网777| 久久久久国产日韩精品网站| 国产成人久久777777| 久久se精品一区精品二区| 97久久久久人妻精品专区| 精品久久久久久无码中文字幕一区| 日本五月天婷久久网站| 尹人香蕉久久99天天拍| 久久婷婷国产剧情内射白浆 | 伊人久久综在合线亚洲2019 |