• <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)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            #

            我在MSVC6里的win32 console工程里面寫了一段這樣的代碼,已經去掉了不必要的代碼已達到注意重點地目點:
            #include  <winbase.h>
            #include  <windows.h>
            switch( dwWaitResult = ::SignalObjectAndWait(
                                               m_hLogItemSendEvent,
                                               m_hLogItemReceivedEvent,
                                               MUTEX_LOCK_TIMEOUT,
                                               FALSE ) )
                {
                case WAIT_OBJECT_0:
                           ::ResetEvent( m_hLogItemReceivedEvent );
                           ::ResetEvent( m_hLogItemSendEvent );
                break;
                case WAIT_TIMEOUT:
                throw AutoLock::CAutoLockTimeoutExc( MUTEX_LOCK_TIMEOUT * 10 );
                break;
                default:
                throw AutoLock::CAutoLockWaitExc( dwWaitResult, ::GetLastError() );
                }
            編譯以后,得到以下兩個錯誤:

            error C2039: 'SignalObjectAndWait' : is not a member of '`global namespace''
            error C2065: 'SignalObjectAndWait' : undeclared identifier

            我在msdn上面已經查找到了SignalObjectAndWait在winbase里面聲明,而在windows里面定義的。但是我在上面的代碼片斷里面已經給出了相關頭文件。卻在編譯的時候出現兩個錯誤。

            問題解決如下:
            #if(_WIN32_WINNT >= 0x0400)
            WINBASEAPI
            DWORD
            WINAPI
            SignalObjectAndWait(
                IN HANDLE hObjectToSignal,
                IN HANDLE hObjectToWaitOn,
                IN DWORD dwMilliseconds,
                IN BOOL bAlertable
                );
            #endif /* _WIN32_WINNT >= 0x0400 */
            在我英文操作系統里面的版本過低,導致出現無法進入上述條件編譯里面,因此需要做的事情是,要么將條件編譯注釋掉,其實問題也不大,反正以后也不會有什么變動,要么就是在stdafx.h最前面重新定義一個_WIN32_WINNT,并且這個定義值應該要大于或者等于0x0400.這樣才是okay的。
            一些其他信息:
            http://topic.csdn.net/u/20080429/16/c12ef43a-5eba-435e-b0bf-f49233cf1d5e.html
            http://www.codeguru.com/forum/showthread.php?t=451931


            posted @ 2008-04-29 19:38 jolley 閱讀(724) | 評論 (0)編輯 收藏

            在vc6里面一般都沒有這個頭文件的,在后面的版本(.NET)都有相關的說明,不過這個是CString包含的頭文件,我之前將open source的代碼移植到win32 application平臺下面,對方的編譯器是vc2003,而我的是用到了vc6,所以就遇到這個問題了,解決辦法有兩種:
            1)在工程里面加入MFCsupport,因為CString是MFC里面的內容。具體做法是project/settings/General/microsoft foundation class處選擇using MFC as a shared dll./ static library.
            在msdn上面有具體的說明。
            可能看起來比較麻煩,不過不好意思,就這樣弄過來防止msdn上面這個文章過舊了,又被刪除了。

            給 ATL EXE 項目添加 MFC 支持



            1. 在包括 Atlbase.h 之前,將以下 #include 指令添加到 StdAfx.h:
                  #include <afxwin.h>   // MFC core and standard components
                        #include <afxext.h>   // MFC extensions
                        #include <afxdisp.h>  // MFC Automation extensions
            2. 更改項目設置以使用 MFC。 在 Project Settings 對話框中,單擊 General 選項卡,然后將 Microsoft Foundation Classes 列表框中的設置更改為 MFC。
            3. 添加 CWinApp 衍生類,并聲明一個該類型的全局變量,如下所示:
            class CMyApp : public CWinApp
                        {
                        public:
                        virtual BOOL InitInstance();
                        virtual int ExitInstance();
                        protected:
                        BOOL m_bRun;
                        };
            4. 用以下 InitInstance 和 ExitInstance 代碼替換 _tWinMain 函數:
            BOOL CMyApp::InitInstance()
                        {
                        // Initialize OLE libraries.
                        if (!AfxOleInit())
                        {
                        AfxMessageBox(_T("OLE Initialization Failed!"));
                        return FALSE;
                        }
                        // Initialize CcomModule.
                        _Module.Init(ObjectMap, m_hInstance);
                        _Module.dwThreadID = GetCurrentThreadId();
                        // Check command line arguments.
                        TCHAR szTokens[] = _T("-/");
                        m_bRun = TRUE;
                        LPCTSTR lpszToken = FindOneOf(m_lpCmdLine, szTokens);
                        while (lpszToken != NULL)
                        {
                        // Register ATL and MFC class factories.
                        if (lstrcmpi(lpszToken, _T("Embedding"))==0 ||
                        lstrcmpi(lpszToken, _T("Automation"))==0)
                        {
                        AfxOleSetUserCtrl(FALSE);
                        break;
                        }
                        // Unregister servers.
                        // There is no unregistration code for MFC
                        // servers. Refer to <LINK TYPE="ARTICLE" VALUE="Q186212">Q186212</LINK> "HOWTO: Unregister MFC
                        // Automation Servers" for adding unregistration
                        // code.
                        else if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
                        {
                        VERIFY(SUCCEEDED(_Module.UpdateRegistryFromResource(IDR_ServerS2B, FALSE)));
                        VERIFY(SUCCEEDED(_Module.UnregisterServer(TRUE)));
                        m_bRun = FALSE;
                        break;
                        }
                        // Register ATL and MFC objects in the registry.
                        else if (lstrcmpi(lpszToken, _T("RegServer"))==0)
                        {
                        VERIFY(SUCCEEDED(_Module.UpdateRegistryFromResource(IDR_ServerS2B, TRUE)));
                        VERIFY(SUCCEEDED(_Module.RegisterServer(TRUE)));
                        COleObjectFactory::UpdateRegistryAll();
                        m_bRun = FALSE;
                        break;
                        }
                        lpszToken = FindOneOf(lpszToken, szTokens);
                        }
                        if (m_bRun)
                        {
                        // Comment out the next line if not using VC 6-generated
                        // code.
                        _Module.StartMonitor();
                        VERIFY(SUCCEEDED(_Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE)));
                        VERIFY(COleObjectFactory::RegisterAll());
                        // To run the EXE standalone, you need to create a window
                        // and assign the CWnd* to m_pMainWnd.
                        LPCTSTR szClass = AfxRegisterWndClass(NULL);
                        m_pMainWnd = new CWnd;
                        m_pMainWnd->CreateEx(0, szClass, _T("SomeName"), 0, CRect(0, 0, 0, 0), NULL, 1234);
                        }
                        return TRUE;
                        }
                        int CMyApp::ExitInstance()
                        {
                        // MFC's class factories registration is
                        // automatically revoked by MFC itself.
                        if (m_bRun)
                        {
                        _Module.RevokeClassObjects();
                        Sleep(dwPause); //wait for any threads to finish
                        }
                        _Module.Term();
                        return 0;
                        }
            5. 對于 Unicode 版本,請確保進入點被設置為 wWinMainCRTStartup,該設置在 Project Settings 對話框中 Link 字段的 Output 類別中。 有關其它信息,請參見 Microsoft Knowledge Base 中的下列文章:
            125750 (http://support.microsoft.com/kb/125750/EN-US/) PRB: 錯誤 LNK2001: “_WinMain@16”: 不能解析的外部符號
            6. 將以下代碼行添加到 COM 接口、窗口過程和導出函數的每個成員函數的開頭:
            AFX_MANAGE_STATE(AfxGetAppModuleState());
            有關 AFX_MANAGE_STATE 的詳細信息,請查詢 VC++ 聯機文檔。
            有關將 MFC 支持添加到 ATL COM AppWizard 項目的詳細信息,請參見下面的 Microsoft Knowledge Base 文章:

            181505 (http://support.microsoft.com/kb/181505/EN-US/) PRB: ATL COM AppWizard 不提供對 .EXE 的 MFC 支持

            回到頂端

            將 MFC 支持添加到 ATL DLL 項目



            執行上面的步驟 1 到步驟 3。

            1. 將 AppWizard 生成的 DllMain 的 DLL_PROCESS_ATTACH 和 DLL_PROCESS_DETACH 中的代碼移到 CMyApp 的 InitInstance 和 ExitInstance,并刪除 DllMain,如下所示:
                  BOOL CMyApp::InitInstance()
                        {
                        _Module.Init(ObjectMap, m_hInstance);
                        return CWinApp::InitInstance();
                        }
                        int CMyApp::ExitInstance()
                        {
                        // MFC's class factories registration is
                        // automatically revoked by MFC itself.
                        if (m_bRun)
                        _Module.RevokeClassObjects();
                        
            2. 將以下代碼行添加到 COM 接口、窗口過程和導出函數的每個成員函數的開頭:
            AFX_MANAGE_STATE(AfxGetStaticModuleState());
            有關其它信息,請參見 Microsoft Knowledge Base 中的下列文章:
            140850 (http://support.microsoft.com/kb/140850/EN-US/) HOWTO: 轉換 DLLTRACE 以使用共享庫中的 MFC

            另外一種辦法就是將atlstr廢掉,采用其他辦法
            因為atlstr實際起作用的是CString,而如果能夠找到CString的替代方案,就可以了。
            替代方案在這里:
            http://www.codeguru.com/forum/showthread.php?t=402543
            一般建議用std::string來完成這些不依賴微軟某種技術的做法。
            在我的項目里面,因為采用的是win32 application工程,并且該項目已經很大了,不想因為這個而在那里增加一些方案1的處理,我采用了方案2。
            posted @ 2008-04-29 10:14 jolley 閱讀(8258) | 評論 (0)編輯 收藏

            進程1:

            #define BUF_SIZE 256
            char fileMapObjectName[] = "FileMappingObject";
            class Sample
            {
            public:
             void set_x(int x){this->xx = x;}
             int get_x(){return this->xx;}
             Sample(){}
            private:
             int xx;
            };

            class EmulatorWindow
            {
            public:
             void set_ew(Sample s){this->sample = s;}
             Sample get_ew(){return this->sample;}
             EmulatorWindow(){}
            private:
             Sample sample;
            };

            int main()
            {
             HANDLE fileMap = CreateFileMapping(
              (HANDLE)0xFFFFFFFF,
              NULL,
              PAGE_READWRITE,
              0,
              BUF_SIZE,
              fileMapObjectName);
             if (NULL == fileMap || GetLastError() == ERROR_ALREADY_EXISTS)
             {
              printf("create file mapping fails! the error code is (%d)",GetLastError());
              return 0;
             }
             Sample s;
             s.set_x(112);
             EmulatorWindow* buffer = (EmulatorWindow*)MapViewOfFile(
              fileMap,
              FILE_MAP_ALL_ACCESS,
              0,
              0,
              BUF_SIZE);
             if (NULL == buffer)
             {
              printf("mapping view of file fails! the error code is (%d)",GetLastError());
              return 1;
             }

             EmulatorWindow ew;
             ew.set_ew(s);

             CopyMemory(buffer,&ew,BUF_SIZE);
             getchar();

             FlushViewOfFile(fileMap,BUF_SIZE);

             UnmapViewOfFile(buffer);
             buffer = NULL;

             CloseHandle(fileMap);
             fileMap = NULL;
             
             return 2;
            }  
            進程2:
            #define BUF_SIZE 256
            char fileMapObjectName[] = "FileMappingObject";

            class Sample
            {
            public:
             void set_x(int x){this->xx = x;}
             int get_x(){return this->xx;}
             Sample(){}
            private:
             int xx;
            };

            class EmulatorWindow
            {
            public:
             void set_ew(Sample s){this->sample = s;}
             Sample get_ew(){return this->sample;}
             EmulatorWindow(){}
            private:
             Sample sample;
            };

            int main()
            {
             HANDLE fileMap = OpenFileMapping(
              FILE_MAP_ALL_ACCESS,
              TRUE,
              fileMapObjectName);
             if (NULL == fileMap)
             {
              printf("opening file mapping fails! the error code is (%d)",GetLastError());
              return 0;
             }
              
             EmulatorWindow* sharedMemory = (EmulatorWindow*)MapViewOfFile(
              fileMap,
              FILE_MAP_ALL_ACCESS,
              0,
              0,
              0);
             if (NULL == sharedMemory )
             {
              printf("mapping view of file fails! the error code is (%d)",GetLastError());
              return 1;
             }

             Sample s = sharedMemory->get_ew();
             int x = s.get_x();

             char buffer[100];
             memset(buffer,0,100);
             sprintf(buffer,"message box is:(%d)",x);
             MessageBox(NULL,buffer,NULL,MB_OK);

             UnmapViewOfFile(sharedMemory);
             sharedMemory = NULL;

             CloseHandle(fileMap);
             fileMap = NULL;

             return 3;

            }
            1)
            這是兩個比較簡單的文件映射例子,其中進程1為源進程,而進程2為目的進程。進程1與進程2進行通信,并且共享一個窗口對象,記得在游戲里面會有很多窗口對象的,因此,在與游戲進行通信的時候就可以共享窗口對象。前段時間在做自動化測試的時候,就經常要與客戶端進行一些交互操作,比如,獲得某個窗口的按鈕狀態,以及文本的信息等,不過這樣做的代價是兩個進程要共享一部分頭文件,起碼像我兩個進程里面都用到了兩段相同的頭文件代碼,不然可能就出現某個窗口對象或者控件對象未聲明或者未定義。

            2)
            另外值得說明的是進程1里面的getchar()用法,很多時候,這個用來延遲操作,并且防止運行過快,特別是在很簡單的結果輸出中,結果會一閃而過,這個時候getchar就起作用了。這里的getchar所起的作用也是延遲的,不過如果將這個getchar()去掉的話,那么你就很可能得到GetLastError()錯誤代碼為2。ERROR_FILE_NOT_FOUND.這個原因是在建立文件對象以后,沒有一段時間緩沖的話,那么進程2有可能找不到在進程空間里面的文件映射,因此就會說ERROR_FILE_NOT_FOUND的錯誤。

            3)
            之前認為共享內存嘛,應該是可以共享任何對象的,但是我在共享一個deque的時候,發現錯了,后來才發現文件映射不能共享指針的,deque是STL的一個序列式容器,而其內部都是一系列的指針組成的,后來在msdn上面發現了一段這樣的話,很震驚:

            Do not store pointers in the memory mapped file; store offsets from the base of the file mapping so that the mapping can be used at any address.
            可以共享的是非指針的用戶自定義類型, 以及內建類型等,不包括含有指針的各種類型。


               


             

            posted @ 2008-04-24 17:04 jolley 閱讀(1438) | 評論 (0)編輯 收藏

                 摘要: 繪制管線
            應用程序階段
            幾何階段 模型和視點變換/光照/投影/裁減/屏幕映射
            光柵階段
              閱讀全文
            posted @ 2008-04-24 09:12 jolley 閱讀(707) | 評論 (1)編輯 收藏

            這回貼上來自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 @ 2008-04-02 16:29 jolley 閱讀(481) | 評論 (0)編輯 收藏

             

            今天第一次寫DLL

            DLL里面有三種類型,win32 DLL, 標準MFC DLL,以及非標準MFC DLL

            他們的區別是,win32 DLL里面主要是用C/C++編寫的,不能調用MFC里面的函數之類的。

            而標準MFC DLL里面可以使用MFC,但是卻不能輸出。

            非標準MFC DLL里面可以使用MFC,并且可以輸出。

            下面是一個簡單的例子

            頭文件

            #pragma once

             

            #ifdef DLLUSAGE_EXPORTS

                 #define SIMPLE_API __declspec(dllexport)

            #else

                 #define SIMPLE_API __declspec(dllimport)

            #endif

             

            SIMPLE_API int AddTwoNumbers(int lhs, int rhs);

             

            實現文件

            SIMPLE_API int AddTwoNumbers(int lhs, int rhs)

            {

            Return lhs + rhs;

            }

             

            在生成 my.DLL 以后,再用

            typedef int (*ADD)(int,int);

            HINSTANCE instance = LoadLibrary("E:\\dllusage.dll");

            if ( NULL == instance)

            {

                     MessageBox(NULL,"加載DLL錯誤",NULL,MB_OK);

                     return 1;    

            }

            ADD myadd = (ADD)GetProcAddress(instance,TEXT("?AddTwoNumbers@@YAHHH@Z"));

            if (NULL == myadd)

            {

                     MessageBox(NULL, "獲取函數地址錯誤",NULL,MB_OK);

                     return 2;

            }

            int result = myadd(5, 6);

             

            這里值得說明的一點是:

            在第二個參數里面采用的是AddTwoNumbersDLL里面的名稱?AddTwoNumbers@@YAHHH@Z,相當于是DLL里面提供給我們調用的接口,如果不采用這樣的寫法,就會出現127錯誤

            ERROR_PROC_NOT_FOUND

            The specified procedure could not be found

            因此我使用那種比較笨的辦法,用view denpends來查找到AddTwoNumbersDLL里面的入口地址,然后再去調用這個這個入口地址。

            或者是采用這樣的方法:

            Extern c

            {

                 SIMPLE_API int AddTwoNumbers(int lhs, int rhs);

            }

            這樣一來的好處就是:

            ADD myadd = (ADD)GetProcAddress(instance,TEXT("AddTwoNumbers "));

            你會發現這樣看起來要舒服一點,這個時候,你用view depends來查看DLL中該函數對應的地址,就會發現變成了AddTwoNumbers

            posted @ 2008-04-02 16:23 jolley 閱讀(320) | 評論 (1)編輯 收藏

            // 摘自代碼大全2第九章
            創建類和子程序的步驟概述.
            1 開始
            2 創建類的總體設計
            3 創建類中的子程序
            4 復查并測試整個類
            5 完成
            其中3與4之間要進行交互,這種交互主要是針對審查子程序進行的,并且2與3之間也要進行交互,這種交互主要針對子程序在類中的總體設計.
            一個思想是:細化跟迭代,并且即使反饋直到類功能和子程序功能都清晰,再到5.
            創建一個類的步驟
            1)創建類的總體設計:
            設計一個類的過程中包含一些特有的設計任務--定義類的特定職責,定義類所要隱藏的秘密,以及精確地定義類的接口所代表的抽象概念,決定這個類是否要從其他類派生而來,以及是否允許其它類再從它派生,指出這個類中關鍵的公用方法,標識并設計出類所需用到的重要數據成員.
            2)創建類中的子程序
            在前述第一個步驟中標識出類的主要子程序之后,還需要創建這些子程序.在編寫各個程序時通常還會引出更多的或重要,或次要的子程序,創建這些新加入的子程序的過程往往還會反過來波及類的總體設計
            3)復審并測試整個類
            通常情況下,子程序在創建的同時也經過了測試,在整個類可以工作之后,應該再對其整體進行復查和測試,以便發現那些在子程序的獨立測試層次上無法測出的問題.
            在創建類的過程中,2),3)還是要求反復進行的,直到類的總體設計是最優的.
            創建子程序的步驟
            創建子程序的過程中涉及到的主要活動: 設計子程序,檢查設計,編寫子程序的代碼,檢查代碼.
            1 開始
            2 設計子程序(主要借助于偽代碼)
            3 檢查設計(主要是檢查偽代碼)
            4 編寫子程序的代碼
            5 復審并測試代碼
            6 完成
            其中2與3是要進行交互的,主要是保證偽代碼的質量,4與5也是要進行交互的,這樣主要保證子程序的質量.
            偽代碼
            偽代碼的指導原則:
            1) 用類似英語的語句來精確描述特定的操作
            2) 避免使用目標編程語言中的語法元素
            3) 在本意的層面上編寫代碼,用偽代碼去描述解決問題的方法的意圖,而不是去寫如何在目標語言中實現這個方法.
            4) 在一個足夠低的層次上編寫代碼,以便可以近乎自動地從它生成代碼.
            通過偽代碼編程過程創建子程序
            檢查先決條件
            在動手去做子程序本身的任何工作之前,應該先查看一下該子程序要做的工作是不是已經定義好了,是不是能夠與整體設計相匹配.另外要結合項目的需求,檢查這個子程序是否真正必須的,至少是間接需要的.
            定義子程序要解決的問題
            陳述出該子程序將要解決的問題,敘述要足夠詳細,以便能去創建這個子程序,如果高層的設計已經足夠詳細,那么這項工作可能已經完成了,在這個高層的設計里至少應該詳細說明下列信息.
            1) 這一子程序將要隱藏的信息
            2) 傳給這個子程序的各項輸入
            3) 從該子程序得到的輸出
            4) 在調用程序之前確保有關的前條件成立(輸入數據的取值位于特定范圍之中,有關的流已經初始化,文件已經打開或者關閉,緩沖區已經填滿或者清空)
            5) 在子程序將控制權交回調用方程序之前,確保其后條件的成立(如輸出數據位于特定范圍之內,流已經初始化,文件已經打開或者關閉,緩沖區已填滿或清空)
            其中4和5一般通過判斷前驅和后繼條件來進行的。前者是保證調用的條件是否成立,而后者是保證程序的返回值是否是合法的。
            為子程序命名
            一般地子程序已經有一個清晰的,無二義性的名字,如果在命名這個子程序的名字的時候,有點困難,那么就說明,對該子程序的設計不是很清楚,而要去改善設計了。
            決定如何測試子程序
            在編寫一個子程序的時候,要想一想怎么才能測試它。這在以后的C/C++測試中都可以部署單元測試工具Xunit.
            在標準庫中搜尋可用的功能
            想用提高代碼的質量和生產率,有一個最重要的途徑就是重用好的代碼。
            考慮錯誤處理
            考慮在子程序中可能出錯的環節,子程序可以用多種方式來處理錯誤,應該特別注意去選擇處理錯誤的方式。
            考慮效率問題
            主要是兩個方面的考慮,一是效率,而另一方面是性能。
            研究算法和數據類型
            如果在可用的程序庫里沒有所需的功能,它也許會在某本算法書中介紹過,決定從頭開始編寫一段復雜的代碼之前,查一下算法書看看有什么可用的內容。如果采用一個已有明確定義的算法,則要保證這個算法正確地轉換為你所用的編程語言。
            編寫偽代碼
            前面的那些步驟主要是為確定一個思路,這在真正編寫程序的時候是很有幫助的,在完成前面的準備工作以后,就可以開始用高層次的偽代碼來寫程序。
            一般是從寫子程序的注釋開始進行編制,主要是說明子程序的功能和目的。
            考慮數據
            在整個過程中的幾個不同環節對子程序所用的數據進行設計。
            檢查偽代碼
            在寫完偽代碼并設計完數據之后,花上幾分鐘時間復雜你寫的偽代碼,然后拋揩這些代碼,想想你該如何向別人解釋這些代碼。
            在偽代碼中試驗一些想法,留下最好的想法
            在你開始編寫代碼之前,應盡可能用偽代碼去嘗試更多的想法。
            編寫子程序的代碼
            1 以偽代碼開始
            2 寫出子程序的聲明
            3 編寫第一條和最后一條語句,然后將偽代碼轉換為高層次的注釋。
            4 每條注釋下面填充代碼
            5 檢查代碼
            6 收尾工作
            7 完成
            其中3,4,5可以按照需求進行重復。
            寫出子程序的聲明
            首先要寫出子程序的接口聲明,即C++中的函數聲明
            把偽代碼轉變為高層次的注釋
            接下來,把第一條和最后一條語句寫出來,在C++中也就是"{"和"}".然后將偽代碼轉變成注釋.
            在每條注釋下面填充代碼
            在偽代碼注釋中的每一句話下面填寫代碼。
            檢查代碼是否需要進一步分解
            方法1:把這段注釋下面的代碼重構(refactor)成一個新的子程序。
            方法2:遞歸地應用偽代碼編程過程。
            檢查代碼
            1) 在腦海里檢查程序中的錯誤。
            理解每行代碼所起的作用,理解為什么需要這行代碼,沒有什么東西會僅僅因為它看上去可行就是正確的。
            編譯子程序
            完成檢查之后,就可以編譯這個程序了。
            最大地發揮編譯子程序所產生的指導建議
            1)把編譯器的警告級別調到最高,通過讓編譯器來檢測錯誤,你可以很容易地查出大量細微的錯誤。
            2)使用驗證工具,可以通過使用類似lint這樣的工具來對C語言這類語言的編譯器所做的檢查結果進行補充檢查。
            3)消除產生錯誤消息和警告的所有根源。
            在調試器中逐步執行代碼
            程序編譯通過了之后,要在調試器中逐行執行,以確保每行代碼都在按照你所期望的方式執行。
            測試代碼
            使用你在開發該子程序期間計劃寫的或者已寫成的測試用例來測試代碼。你可能需要開發一些腳手架來支持你的測試用例
            消除程序中的錯誤
            一旦檢測到錯誤,就一定要把它除掉。
            收尾工作
            檢查子程序的接口
            確定所有的輸入,輸出數據都參與了計算,并且所有的參數也都用到了。
            檢查整體的設計質量
            檢查子程序中的變量
            檢查子程序的語句和邏輯
            檢查子程序的布局
            檢查子程序的文檔
            除去冗余的注釋。
            小結:
            之前一直在寫程序,但是發現時不時思路很亂,也沒有有層次地,有系統地去思考這些類和子程序的設計,只是去實現一個功能,并且能夠達到所要的目的就可以了,后來發現經常出問題,很常見的就是考慮不周全,在編制代碼以后,才開始反悔,后悔當初的設計,然后對程序產生了消極的情緒,讓我感覺不爽,看了代碼大全,發現提供了可行的方法.而且思路比以前清晰多了,感覺這個方法很有效,所以記錄在這里.


             

            posted @ 2008-03-01 12:09 jolley 閱讀(1001) | 評論 (0)編輯 收藏

            僅列出標題
            共4頁: 1 2 3 4 
            久久综合给合综合久久| 91精品国产高清久久久久久io| 精品久久久久久99人妻| 香港aa三级久久三级老师2021国产三级精品三级在 | AV无码久久久久不卡网站下载| 亚洲精品国精品久久99热一| 久久精品国产亚洲综合色| 久久久久亚洲AV无码去区首| 久久精品亚洲一区二区三区浴池 | 色偷偷88欧美精品久久久| 久久SE精品一区二区| 久久99国产一区二区三区| 色综合久久综合中文综合网| 久久青青草原精品国产软件| av无码久久久久不卡免费网站| 亚洲国产精品综合久久一线 | 色综合久久综精品| 囯产精品久久久久久久久蜜桃 | 一本色道久久综合| 国产午夜精品久久久久九九| 久久超碰97人人做人人爱| 久久人妻AV中文字幕| 久久婷婷色香五月综合激情| 久久精品视频91| 久久综合综合久久狠狠狠97色88| 无码人妻久久一区二区三区| 久久久久久久波多野结衣高潮| 久久久精品日本一区二区三区| 91精品国产9l久久久久| 国产三级久久久精品麻豆三级 | 俺来也俺去啦久久综合网| 亚洲精品无码久久久久| 久久精品国产亚洲AV香蕉| 久久九九久精品国产免费直播| 99久久国产亚洲综合精品| 蜜臀久久99精品久久久久久| 午夜视频久久久久一区| 欧美午夜A∨大片久久 | 亚洲AV无码久久精品狠狠爱浪潮 | 日批日出水久久亚洲精品tv| 国产精品美女久久久久av爽 |