C++函數的匯出與匯入

來源:互聯網
上載者:User

標籤:main   property   bsp   dllimport   keyword   _stdcall   entry   call   iso   

DLL使用

(1)隱式連結到 DLL 的可運行檔案在產生時連結到匯入庫(.lib檔案)。

(2)採用顯式串連(LoadLibrary和GetProcAddress)時,不須要.lib檔案。

函數匯出方式

(1)源碼中的 __declspec(dllexport) keyword 
(2).def 檔案裡的 EXPORTS 語句 
(3)LINK 命令中的 /EXPORT 規範 
全部這三種方法能夠用在同一個程式中。

LINK 在產生包括匯出的程式時還建立匯入庫,除非產生中使用了 .exp 檔案。


匯出

CppDynamicLinkLibrary.cpp

#include "CppDynamicLinkLibrary.h"#include <strsafe.h>#pragma region DLLMainBOOL APIENTRY DllMain(HMODULE hModule,                      DWORD  ul_reason_for_call,                      LPVOID lpReserved                      ){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}#pragma endregion#pragma region Global Data// An exported/imported global data using a DEF file// Initialize it to be 1int g_nVal1 = 1;// An exported/imported global data using __declspec(dllexport/dllimport)// Initialize it to be 2SYMBOL_DECLSPEC int g_nVal2 = 2;#pragma endregion#pragma region Ordinary Functions// An exported/imported cdecl(default) function using a DEF fileint /*__cdecl*/ GetStringLength1(PCWSTR pszString){    return static_cast<int>(wcslen(pszString));}// An exported/imported stdcall function using __declspec(dllexport/dllimport)SYMBOL_DECLSPEC int __stdcall GetStringLength2(PCWSTR pszString){    return static_cast<int>(wcslen(pszString));}#pragma endregion#pragma region Callback Function// An exported/imported stdcall function using a DEF file// It requires a callback function as one of the argumentsint __stdcall CompareInts(int a, int b, PFN_COMPARE cmpFunc){// Make the callback to the comparison function// If a is greater than b, return a;     // If b is greater than or equal to a, return b.    return ((*cmpFunc)(a, b) > 0) ? a : b;}#pragma endregion#pragma region Class// Constructor of the simple C++ classCSimpleObject::CSimpleObject(void) : m_fField(0.0f){}// Destructor of the simple C++ classCSimpleObject::~CSimpleObject(void){}float CSimpleObject::get_FloatProperty(void){return this->m_fField;}void CSimpleObject::set_FloatProperty(float newVal){this->m_fField = newVal;}HRESULT CSimpleObject::ToString(PWSTR pszBuffer, DWORD dwSize){    return StringCchPrintf(pszBuffer, dwSize, L"%.2f", this->m_fField);}int CSimpleObject::GetStringLength(PCWSTR pszString){    return static_cast<int>(wcslen(pszString));}#pragma endregion


CppDynamicLinkLibrary.def

LIBRARY   CppDynamicLinkLibraryEXPORTS   GetStringLength1     @1   CompareInts  @2   g_nVal1DATA

匯入

CppLoadLibrary.cpp

#pragma region Includes#include <stdio.h>#include <windows.h>#pragma endregion// Function pointer types for functions exported from the DLL moduletypedef int     (_cdecl* LPFNGETSTRINGLENGTH1)      (PCWSTR);// CALLBACK, aka __stdcall, can only be used for stdcall methods. If it is// used for __cdecl methods, this error will be thrown in runtime: The value // of ESP was not properly saved across a function call. This is usually a // result of calling a function declared with one calling convention with a// function pointer declared with a different calling convention.typedef int     (CALLBACK* LPFNGETSTRINGLENGTH2)    (PCWSTR);// Type-definition of the ‘PFN_COMPARE‘ callback function, and the CompareInts // function that requires the callback as one of the arguments.typedef int     (CALLBACK* PFN_COMPARE)             (int, int);typedef int     (CALLBACK* LPFNMAX)                 (int, int, PFN_COMPARE);////   FUNCTION: IsModuleLoaded(PCWSTR)////   PURPOSE: Check whether or not the specified module is loaded in the //   current process.////   PARAMETERS://   * pszModuleName - the module name////   RETURN VALUE: The function returns TRUE if the specified module is //   loaded in the current process. If the module is not loaded, the function //   returns FALSE.//BOOL IsModuleLoaded(PCWSTR pszModuleName) {// Get the module in the process according to the module name.HMODULE hMod = GetModuleHandle(pszModuleName);    return (hMod != NULL);}////   FUNCTION: Max(int, int)////   PURPOSE: This is the callback function for the method Max exported from //   CppDynamicLinkLibrary.dll////   PARAMETERS://   * a - the first integer//   * b - the second integer////   RETURN VALUE: The function returns a positive number if a > b, returns 0 //   if a equals b, and returns a negative number if a < b.//int CALLBACK Max(int a, int b){return (a - b);}int wmain(int argc, wchar_t *argv[]){    BOOL fLoaded = FALSE;    HINSTANCE hModule = NULL;// The name of the module to be dynamically-loaded.PCWSTR pszModuleName = L"CppDynamicLinkLibrary";// Check whether or not the module is loaded.fLoaded = IsModuleLoaded(pszModuleName);    wprintf(L"Module \"%s\" is %sloaded\n", pszModuleName, fLoaded ? L"" : L"not ");// Dynamically load the library.    wprintf(L"Load the library\n");hModule = LoadLibrary(pszModuleName);if (hModule == NULL){        wprintf(L"LoadLibrary failed w/err 0x%08lx\n", GetLastError());        goto Cleanup;    }    // Check whether or not the module is loaded.fLoaded = IsModuleLoaded(pszModuleName);    wprintf(L"Module \"%s\" is %sloaded\n", pszModuleName, fLoaded ? L"" : L"not ");    //     // Access the global data exported from a module.    //     // Dynamically-loaded DLL does not allow you to access the global data     // exported from the DLL.    //     // Call the functions exported from a module.    //     PCWSTR pszString = L"HelloWorld";    int nLength;    // Call int /*__cdecl*/ GetStringLength1(PWSTR pszString);    LPFNGETSTRINGLENGTH1 lpfnGetStringLength1 = (LPFNGETSTRINGLENGTH1)GetProcAddress(hModule, "GetStringLength1");    if (lpfnGetStringLength1 == NULL)    {        wprintf(L"GetStringLength1 cannot be found (Error: 0x%08lx)\n",             GetLastError());        goto Cleanup;    }nLength = lpfnGetStringLength1(pszString);    wprintf(L"Function: GetStringLength1(\"%s\") => %d\n", pszString, nLength);    // Call int __stdcall GetStringLength2(PWSTR pszString);    LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)GetProcAddress(hModule, "[email protected]");    if (lpfnGetStringLength2 == NULL)    {        wprintf(L"GetStringLength2 cannot be found (Error: 0x%08lx)\n",             GetLastError());        goto Cleanup;    }    nLength = lpfnGetStringLength2(pszString);    wprintf(L"Function: GetStringLength2(\"%s\") => %d\n", pszString, nLength);    //    // Call the callback functions exported from a module.    //    // Call int __stdcall CompareInts(int a, int b, PFN_COMPARE cmpFunc);    LPFNMAX lpfnMax = (LPFNMAX)GetProcAddress(hModule, "CompareInts");    if (lpfnMax == NULL)    {        wprintf(L"CompareInts cannot be found (Error: 0x%08lx)\n", GetLastError());        goto Cleanup;    }    int max = lpfnMax(2, 3, &Max);    wprintf(L"Function: CompareInts(2, 3,Max) => %d\n", max);    //    // Use the class exported from a module.    //    // Dynamically-loaded DLL does not allow you to use the class exported     // from the DLL.Cleanup:    if (hModule)    {        // Attempt to free and unload the library.        wprintf(L"Unload the dynamically-loaded DLL\n");        if (!FreeLibrary(hModule))        {            wprintf(L"FreeLibrary failed w/err 0x%08lx\n", GetLastError());        }    }        // Check whether or not the module is loaded.fLoaded = IsModuleLoaded(pszModuleName);    wprintf(L"Module \"%s\" is %sloaded\n", pszModuleName, fLoaded ? L"" : L"not ");return 0;}


示範範例project地址:http://download.csdn.net/detail/x356982611/8071757

C++函數的匯出與匯入

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.