一、
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;
}