zoukankan      html  css  js  c++  java
  • C++函数的导出与导入

    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 DLLMain
    BOOL 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 1
    int g_nVal1 = 1;
    
    
    // An exported/imported global data using __declspec(dllexport/dllimport)
    // Initialize it to be 2
    SYMBOL_DECLSPEC int g_nVal2 = 2;
    
    #pragma endregion
    
    
    #pragma region Ordinary Functions
    
    
    // An exported/imported cdecl(default) function using a DEF file
    int /*__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 arguments
    int __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++ class
    CSimpleObject::CSimpleObject(void) : m_fField(0.0f)
    {
    }
    
    
    // Destructor of the simple C++ class
    CSimpleObject::~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   CppDynamicLinkLibrary
    EXPORTS
       GetStringLength1     @1
       CompareInts  	@2
       g_nVal1		DATA

    导入

    CppLoadLibrary.cpp

    #pragma region Includes
    #include <stdio.h>
    #include <windows.h>
    #pragma endregion
    
    
    // Function pointer types for functions exported from the DLL module
    
    typedef 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
    ", pszModuleName, fLoaded ? L"" : L"not ");
    
    	// Dynamically load the library.
        wprintf(L"Load the library
    ");
    	hModule = LoadLibrary(pszModuleName);
    	if (hModule == NULL)
    	{
            wprintf(L"LoadLibrary failed w/err 0x%08lx
    ", GetLastError());
            goto Cleanup;
        }
    
        // Check whether or not the module is loaded.
    	fLoaded = IsModuleLoaded(pszModuleName);
        wprintf(L"Module "%s" is %sloaded
    ", 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)
    ", 
                GetLastError());
            goto Cleanup;
        }
    	nLength = lpfnGetStringLength1(pszString);
        wprintf(L"Function: GetStringLength1("%s") => %d
    ", pszString, nLength);
    
        // Call int __stdcall GetStringLength2(PWSTR pszString);
        LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)GetProcAddress(hModule, "_GetStringLength2@4");
        if (lpfnGetStringLength2 == NULL)
        {
            wprintf(L"GetStringLength2 cannot be found (Error: 0x%08lx)
    ", 
                GetLastError());
            goto Cleanup;
        }
        nLength = lpfnGetStringLength2(pszString);
        wprintf(L"Function: GetStringLength2("%s") => %d
    ", 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)
    ", GetLastError());
            goto Cleanup;
        }
        int max = lpfnMax(2, 3, &Max);
        wprintf(L"Function: CompareInts(2, 3,Max) => %d
    ", 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
    ");
            if (!FreeLibrary(hModule))
            {
                wprintf(L"FreeLibrary failed w/err 0x%08lx
    ", GetLastError());
            }
        }
        
        // Check whether or not the module is loaded.
    	fLoaded = IsModuleLoaded(pszModuleName);
        wprintf(L"Module "%s" is %sloaded
    ", pszModuleName, fLoaded ? L"" : L"not ");
    
    	return 0;
    }


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

  • 相关阅读:
    #{}和${}的区别
    Shiro 的优点
    SpringSecurity 和 Shiro的之间的比较
    shiro的组件
    Apache Shiro 的三大核心组件
    Maven的工程类型有哪些?
    Maven仓库是什么
    什么是Maven?
    shiro有哪些组件?
    Apache Shiro 的三大核心组件
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6962142.html
Copyright © 2011-2022 走看看