通過GetProcAddress函數動態調用dll中地函數,是否必須通過extern C聲明匯出函數?

來源:互聯網
上載者:User
『通過GetProcAddress函數動態調用dll中地函數,是否必須通過extern C聲明匯出函數?』  


通過GetProcAddress函數動態調用dll中的函數,是否必須通過extern "C"聲明匯出函數?

[已結貼,結貼人:darongtou]

    如題,網上搜了N多資料,一直找不到確定的答案,目前我的答案是“是”。

    晚上因為一個程式,好好研究了一下。

    很多資料上都只是說明“如果沒有   extern   "C"   修飾,輸出函數僅僅能從   C++   代碼中調用。”
    卻並沒有明確這個調用是通過顯式調用還是隱式調用,我也一直沒有看到過有代碼是通過顯示調用沒有extern   "C"   修飾的匯出函數。

    MSDN上也只是說
    The   spelling   and   case   of   the   function   name   pointed   to
      by   lpProcName   must   be   identical   to   that   in   the  
    EXPORTS   statement   of   the   source   DLL's   module-definition  
    (.DEF)   file.   The   exported   names   of   Win32   API   functions
      may   differ   from   the   names   you   use   when   calling  
    these   functions   in   your   code.  

    下面再從理論方面進行一些分析:
    GetProcAddress函式宣告是:
    FARPROC   GetProcAddress(
        HMODULE   hModule,         //   handle   to   DLL   module
        LPCSTR   lpProcName       //   name   of   function
    );
    C++是支援函數重載的,也就是說允許多個不同的函數可以有同樣的函數名,如果不通過extern       "C"修飾,就可以輸出相同的函數名。
    這樣,就和GetProcAddress函式宣告不一致了,所以推斷不能動態調用沒有extern       "C"修飾的匯出函數,因為GetProcAddress函數是通過函數名來唯一確定被調用函數的地址的。

    歡迎大家討論!

    100 

    第1個回答
    顯示調用必須使用extern   "C"修飾符。隱式調用可以使用任何類型,但只有C++能調用沒有extern   "C"修飾的匯出函數。

    GetProcAddress是一種通用的擷取函數進入點的API,能被任何語言調用,所以限制一定比較多,比如它的參數一定是一個ANSI串(作業系統並未提供UNICODE版本)。

      第2個回答
      我的理解是這樣的:GetProcAddress實際上跟你直接調用myfunc()一樣,都是查詢Export表來得到函數地址再去調用,因此你修飾符不對就會造成找不到entry,是不行的。當然我沒試過,沒有完全的把握。

        第3個回答
        C函數和C++函數的名稱是不一樣的,可以使用工具來查看,比如Dependency   Walker。如果你想實驗,可以根據工具看到的名稱來調用GetProcAddress試試

          第4個回答
          主要是就是名字的問題

          有兩種例外情況可以不加extern   “C”:
          1。如果不是用C++編譯器而是用C編譯DLL,名字不會變,可以不加extern   "C"
          2。如果DLL的使用者知道是用C++編譯器編譯DLL,不加extern   “C”也可以,因為他知道名字改變的規則。調用GetProcAddress,把函數名字改了就是了

            第5個回答
            C++編譯器和C編譯器編譯後產生的函數名不一樣。
            GetProcAddress認為是cdecl的函數,而
            編譯DLL的是VC++,所以要加一個extern   “C"的修飾符
            指明以cdecl的方式產生函數。

              第6個回答
              發現不用加extern               "C"也是可以的,只要在調用端用修飾過的函數名即可,不能用原函數名。
              例子關鍵代碼如下:
              ----------------------------
              DLL部分:
              //   This   is   an   example   of   an   exported   function.
              DLL1_API   int   __cdecl   fnDll1(void)
              {
              return   42;
              }
              輸出的修飾函數名為?fnDll1@@YAHXZ

              DLL1_API   int   __cdecl   fnDll1(int   a)
              {
              return   42+a;
              }

              輸出的修飾函數名為?fnDll1@@YAHH@Z
              -----------------------------
              EXE部分:
              HINSTANCE   hModule   =   LoadLibrary("dll1.dll");
              ASSERT(hModule);
              typedef   int   (*fnDll1)();
              fnDll1   pfnDll1   =   NULL;
              //VERIFY(pfnDll1   =   (fnDll1)::GetProcAddress(hModule,   "fnDll1"));
              VERIFY(pfnDll1   =   (fnDll1)::GetProcAddress(hModule,   "?fnDll1@@YAHXZ"));
              ASSERT(pfnDll1()   ==   42);

              typedef   int   (*fnDll2)(int);
              fnDll2   pfnDll2   =   NULL;
              VERIFY(pfnDll2   =   (fnDll2)::GetProcAddress(hModule,   "?fnDll1@@YAHH@Z"));
              ASSERT(pfnDll2(3)   ==   45);
              ---------------------------
              這事暫時可以告一段落了,實驗還是最有力的證明。

              相關文章

              聯繫我們

              該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

              如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

              A Free Trial That Lets You Build Big!

              Start building with 50+ products and up to 12 months usage for Elastic Compute Service

              • Sales Support

                1 on 1 presale consultation

              • After-Sales Support

                24/7 Technical Support 6 Free Tickets per Quarter Faster Response

              • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.