DLL编程基础
来源:互联网 发布:软件注册码怎么破 编辑:程序博客网 时间:2024/06/04 19:28
DLL是组成windows系统的基石,在很多情况下的编程是离不开它的,今天说一下关于DLL编程的一些基础,也是必须要了解的。
主要分为两大类:(1)DLL的编写 (2)DLL的使用
1.DLL的编写
DLL编写需要一个头文件和一个源文件,头文件用于声明,源文件用于实现:
下面是我编写的一个例子程序的头文件中的内容:
// The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the TESTDLL_EXPORTS// symbol defined on the command line. this symbol should not be defined on any project// that uses this DLL. This way any other project whose source files include this file see // TESTDLL_API functions as being imported from a DLL, wheras this DLL sees symbols// defined with this macro as being exported.#ifdef TESTDLL_EXPORTS#define TESTDLL_API __declspec(dllexport)#else#define TESTDLL_API __declspec(dllimport)#endif// This class is exported from the TestDll.dllclass TESTDLL_API CTestDll {public:CTestDll(void);// TODO: add your methods here.};extern TESTDLL_API int nTestDll;TESTDLL_API int fnTestDll(void);extern "C" __declspec(dllexport) int add( int a , int b ) ;
下面是对应的源文件的内容:
// TestDll.cpp : Defines the entry point for the DLL application.//#include "stdafx.h"#include "TestDll.h"BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:MessageBox( NULL , "Message" , "Inject OK!" , NULL ) ;break ;case DLL_THREAD_ATTACH:MessageBox( NULL , "Message" , "Inject Ok!" , NULL ) ;break ;case DLL_THREAD_DETACH:MessageBox( NULL , "Message" , "UnInject Ok!" , NULL ) ;break ;case DLL_PROCESS_DETACH:MessageBox( NULL , "Message" , "UnInject Ok!" , NULL ) ;break ; } return TRUE;}// This is an example of an exported variableTESTDLL_API int nTestDll=0;// This is an example of an exported function.TESTDLL_API int fnTestDll(void){return 42;} __declspec(dllexport) int add( int a , int b ){return a + b ;}// This is the constructor of a class that has been exported.// see TestDll.h for the class definitionCTestDll::CTestDll(){ return; }
DLL的编写过程中最主要的区别是如何导出函数/变量/C++类,有两种方法:
(1)使用.def文件
这种方法用的不多,我们主要说第二种
(2)使用extern "C" _declspec(dllexport)
在函数的前面加上以上代码(因为DLL主要用于导出函数所以导出变量与C++类就不说了)即可。
有一点要注意的是,一定要要加上extern ”C",这样编译器就会按照C语言的编译方式来处理符号(函数),那么就不会使用C++的编译方法把我们的函数改的面目全非了。假如不加上,那么在使用GetProcAddress函数寻找函数的地址的时候是找不到的。
二.DLL的使用
在我们的exe程序中,我们需要调用DLL的时候我们有两种使用方法:
(1)隐式调用
这种方法我们需要在生成dll的过程中的dll文件和lib文件,在很多时候我们都是使用的这种方法,例如在socket编程中我们使用#pragama comment ( lib , "ws2_32.lib" ) 来导入winsock支持网络编程的dll,这样我们就能使用它其中的函数了。
同样的道理,在隐式编写程序的时候我们一样使用#pragma comment 宏来导入我们需要的模块。
#pragma comment ( lib , "TestDll.lib") _declspec(dllimport) int add( int a , int b ) ;
如上,我们隐私调用只要在文件头加上上面两行即可。
(2)显式调用
显式调用相对于隐私调用更急灵活,使用的API是LoadLibrary(实际上是一个宏)。
#include "stdio.h"#include "windows.h"// #pragma comment ( lib , "TestDll.lib") // // _declspec(dllimport) int add( int a , int b ) ;// ////////////////////////////////////////////////////////////////////////////// 在显式加载的的情况下要注意,在DLL中声明导出函数的时候一定要在其// 声明的位置加上 extern "C" // 否则,早动态导入函数的时候GetProAddress是找不到相应的函数的//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////typedef int ( * ADD_FUNC) ( int , int ) ;int main(){HMODULE hMod = LoadLibrary( "TestDll.dll") ;if( hMod ){ADD_FUNC add_funcPointer = ( ADD_FUNC )GetProcAddress( hMod , "add" ) ;if( add_funcPointer ){printf( "%d\n" , add_funcPointer( 7 , 8 ) ) ;}FreeLibrary( hMod ) ;}// printf( "%d\n" , add( 7 , 8 ) ) ;return 0 ;}
- DLL编程基础
- windows DLL编程基础
- MFC的DLL编程基础
- Windows核心编程:DLL基础
- Windows核心编程 DLL基础
- windows核心编程---DLL基础
- 动态链接库DLL基础编程
- Windows核心编程--DLL基础--摘录
- Windows核心编程(十八)DLL基础
- Windows核心编程 第十九章 DLL基础
- Windows核心编程之DLL基础
- 《Windows核心编程5》第19章-DLL基础
- WINDOWS核心编程——DLL基础和实操
- 《Windows核心编程》读书笔记十九章 DLL基础
- DLL基础
- DLL基础
- DLL基础
- DLL基础
- 如何学习运营,如何思考运营
- C# 首个程序
- java final static
- Modules的概念及使用
- 玩转STM32F0 Value Line Discovery 之 点亮LED
- DLL编程基础
- ubuntu下的c语言的第一天
- Array和ArrayList的异同点
- Makefile经典教程(掌握这些足够)
- uva 11995 I Can Guess the Data Structure!(数据结构:基础)
- NandFlash简介
- Linux下完美驱动HTC Android手机的Internet传输(通过USB共享电脑网络)
- POJ1151 Atlantis 【扫描线】
- VMware中CentOS设置静态IP