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

  

原文地址:https://www.cnblogs.com/2012harry/p/4026309.html