Dll导出方法和说明
一、
dll函数和类有两种导出方法:
1、.def文件导出;
2、__declspec(dllexport)导出;
dll方法和类的导入:
1、静态方式,加载lib和头文件,接着调用即可;
2、动态方式,load dll,使用GetProcAddress动态获取函数指针地址;
二、下面是使用.def导出方式的代码
dll代码:
FuncImp.h
#ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif #ifndef TESTAPI #define TESTAPI __stdcall #endif /* TESTDLL_API int TESTAPI Add(int a, int b); TESTDLL_API int TESTAPI Sub(int a, int b); */ /* 1、.def导出函数,只需要下面这种导出即可,不需要__declspec(dllexport),但是必须要指定__stdcall 2、如果不是.def导出,单纯的是.h文件声明导出,就需要__declspec(dllexport) 注:什么时候用.def,什么时候用__declspec(dllexport)导出 如果需要导出类接口,就需要用__declspec(dllexport)导出的方法,不要使用.def(但是这种也是可以的,只是使用比较麻烦,已经记不得怎么使用了) 其他情况,二者都可以;.def导出方法相对偏向一点 */ int TESTAPI Add(int a, int b); int TESTAPI Sub(int a, int b);
FuncImp.cpp
#include <stdafx.h> #include "FuncImp.h" /* TESTDLL_API int TESTAPI Add(int a, int b) { return a + b; } TESTDLL_API int TESTAPI Sub(int a, int b) { if (a > b) { return a - b; } else { return b - a; } } */ int TESTAPI Add(int a, int b) { return a + b; } int TESTAPI Sub(int a, int b) { if (a > b) { return a - b; } else { return b - a; } }
还要要注意的一点:dll项目的Linker--->Input--->Module Definition File == TestModule.def
.def文件如下:
LIBRARY "TestDll"
EXPORTS
Add @1
Sub @2
三、使用Dll导出函数的两种方式(静态动态)
// UseTestDll.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "../TestDll/FuncImp.h" #include <Windows.h> //#include <ShlObj.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") #include <strsafe.h> #include <atlstr.h> #include <iostream> using namespace std; /* dll的导出函数,分静态和动态两种。 1、静态的需要导入其.lib文件(#pragma comment(lib, "***.lib")) 2、动态导入函数,使用GetProcAddress */ typedef int (__stdcall *pFunc_Add)(int a, int b); typedef int (__stdcall *pFunc_Sub)(int a, int b); #define Func_Add_Name "Add" #define Func_Sub_Name "Sub" void UseFuncByStatic() { #pragma comment(lib, "..\\Debug\\TestDll.lib") cout<<Add(2,3)<<endl; cout<<Sub(2,3)<<endl; } void UseFuncByDynamic() { TCHAR* m_pszModuleName = NULL; TCHAR* m_pszExePath = NULL; { m_pszModuleName = new TCHAR[MAX_PATH]; ZeroMemory(m_pszModuleName, MAX_PATH * sizeof(TCHAR)); DWORD dwLength = ::GetModuleFileName(NULL, m_pszModuleName, MAX_PATH); m_pszExePath = new TCHAR[MAX_PATH]; ZeroMemory(m_pszExePath, MAX_PATH * sizeof(TCHAR)); StringCchCopy(m_pszExePath, MAX_PATH, m_pszModuleName); PathRemoveFileSpec(m_pszExePath); } HMODULE hModule; CString cstrDllPath = m_pszExePath; PathAppend(cstrDllPath.GetBuffer(MAX_PATH), _T("TestDll.dll")); cstrDllPath.ReleaseBuffer(); hModule = LoadLibrary(cstrDllPath.GetString()); if (NULL == hModule) { return; } pFunc_Add pFuncModule_Add; pFunc_Sub pFuncModule_Sub; pFuncModule_Add = (pFunc_Add)GetProcAddress(hModule, Func_Add_Name); pFuncModule_Sub = (pFunc_Sub)GetProcAddress(hModule, Func_Sub_Name); cout<<pFuncModule_Add(2,3)<<endl; cout<<pFuncModule_Sub(2,3)<<endl; delete []m_pszModuleName; delete []m_pszExePath; } int _tmain(int argc, _TCHAR* argv[]) { cout<<"static"<<endl; UseFuncByStatic(); cout<<"dynamic"<<endl; UseFuncByDynamic(); return 0; }