DLL实用技巧——namespace, 生成后事件

原创 2007年10月10日 00:17:00

本文为原创,转载或其他用途请注明出处:

http://blog.csdn.net/ydbcsdn/archive/2007/10/10/1817622.aspx

http://blog.csdn.net/ydbcsdn

作者E-mail: yaodebo@163.com

本人不才, 暂时写不出什么好文,   今天, 我想在这里写一点我认为比较实用的技巧。

在项目稍微大点的时候,我们不可避免得要把某些功能模块分开来进行开发,动态链接库对我们来说是个不错的选择。

一、DLL简介

库文件有两种,一个是动态链接库,一种是静态链接库,这里只讲其中的动态链接库,本文介绍的对象是Windows 32 DLL MFC扩展类DLL

动态链接库生成后,提供给其他的动态库、静态库或应用程序进行调用。做后库文件后,需要提供给调用方这样几个文件:

1.  DLL文件 —— 包含编译链接好的代码和变量

2.  LIB文件 —— 包含一系列对DLL文件中资源的描述

3.  H头文件 —— 声明DLL中可以被用户引用的类型、宏、变量、函数等

对调用者来说,调用DLL有隐式调用和显式调用两种不同的方法。下面分别进行简要介绍:

1 显式调用DLL

调用者在编译链接过程中,并不需要链接和包含任何与DLL相关的文件。不过,我要预先了解DLL中导出函数的原型和函数名称,才能正确的调用DLL中的函数。例如:DLL中有这样的一个导出函数:

int MyFunction(int a, int b); 

假如我们知道上述的这个函数,那么我们在程序中调用这个函数的步骤如下:

1 调用 HMODULE  LoadLibray(LPCTSTR lpszDLL)   

函数功能:将DLL文件加载到应用程序的地址空间

    数:lpszDLL 为字符串,表示要加载的DLL文件的名称(包含路径)

    回:HMODULE 类型(即HINSTANCE类型)

例如:

   HINSTANCE hIns = LoadLibrary(MyFunc.dll);

   If(hIns == NULL)

{

    AfxMessageBox(Failed to Load MyFunc.dll!);

}

      

   2、调用 FRAPRO GetProcAddress(HMODULE hModule, LPCTSTR lpszProName)

       函数功能:从一个模块中查找指定名称的函数,并返回函数在应用程序中的首地址。

           数: hModule 为模块句柄(我们需要传入LoadLibrary的返回值)

                  lpszProName为函数的名称

   我们得到指针后,需要根据我们掌握的函数的原型进行强制的指针类型转换。

例如:

 // 对函数 int MyFunction(int a, int b);  

HINSTANCE hIns = LoadLibrary(MyFunc.dll);

   typedef (*int LPFUNCTION)(int, int);  // 函数原型的重定义

   LPFUNCTION lpFun;                     // 函数指针声明

   lpFun = (LPFUNCTION)(GetProcAddress(hIns, MyFunction));

// 调用方法
      int a, b;

int nResult = lpFun(a, b)

 

2 隐式调用DLL

调用者需要包含DLL提供的3个文件—— H头文件、LIB文件、DLL文件。以下代码最直接有效:

#include  xxxx.h

#pragma comment(lib, xxxx.lib)

以后,在需要调用DLL中函数和类型的地方可以直接调用函数,就如同调用windows API一样。

 

二、值得关注的地方

1namespace 的用法:

DLL中可以导出很多用户自定义的函数、类型、全局变量等。但是,我们有必要注意到这样的一种情形:我们写的DLL中有一些函数,能满足我们的需要,同时,我们也需要用到其他人写的DLL,但是不幸的是,这两个DLL中有同名的函数。尽管你可能还没碰到这样的情形,但是你可能要开始留意这个问题了,那么有什么好的办法来避免吗?

我们可以使用namespace namespace能将用户自定义的类型、变量、函数等全部归类到一起,当我们调用函数遇到冲突的时候,我们就可以显式地指定调用某个namespace中的这个函数。如 MyNameSpace::MyFunction();

现在我们的任务是:在普通DLL的基础上,进行更改,以便支持namespace

首先,我们需要在H文件的导出声明中添加 namespace MySpace{},并将所有要导出的函数都放在{}中。试试编译你的程序,你可能会发现,编译无法通过,提示的是很多函数都是未声明的了,为什么会这样?答案是:要调用namespace中的资源,必须先将namespace引用。引用方法:using namespace MySpace;

这时,你再编译,恭喜你,通过了!但是,你用 VC6自带的Dependence 打开这个DLL,你会发现在导出函数列表中没有任何函数了,换句话说,这个DLL没导出函数了。为什么呢?同样是语法问题:我们对这些导出函数进行实现的时候,需要进行一些改变,改成类似于C++类的函数声明方式。如函数 void MyFunction(), 应该这样写实现:

void MySpace::MyFuntion(){}

2)“生成后事件”的使用

 VC的集成化开发环境提供了很多意想不到的东西,其中有一个叫“生成后事件”的项目设置选项就有实用!

 VC2003中的这项设置在“项目属性”中,如果您不知道什么是“项目属性”那就关闭网页吧(开个玩笑,都快12点了,比较累)。

顾名思义,“生成后事件”就是项目执行生成工程文件之后要做的事情。对于DLL,我们就可以利用这一点,很方便地实现将最新的DLLLIBH文件拷贝到指定的地点,这样其他项目需要的调用库的时候就能保证调的库是最新的而且匹配好的,不用你到处去找了。

要实现这点,你需要做些什么呢?你只需要在“生成后事件”对应的编辑框里写上几句批处理语句,如;

copy .//debug//123.dll  ..//Lib//123.dll

copy .//debug//123.lib  ..//Lib//123.lib

copy .//123.h   ..//lib//123.h                               

这样就可以了。然后在执行完生成dll后,就会执行这3条复制文件的语句,如果写的命令格式正确,那么在消息窗里就可以看到复制文件成功的提示了。

 

 

DLL的原理

一,DLL的原理  1,动态链接程序库  动态链接程序库,全称:Dynamic Link Library,简称:DLL,作用在于为应用程序提供扩展功能。应用程序想要调用DLL文件,需要跟其进行“动...
  • helloworld201456
  • helloworld201456
  • 2014年06月09日 06:19
  • 242

使DLL在系统中仅有一个实例

动态库是一种可执行文件,在操作系统支持下,它成为独立于进程的共享可执行文件。MSDN对动态库作如下概念定义:动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用...
  • whf727
  • whf727
  • 2008年03月26日 14:47
  • 595

DLL实用技巧——namespace, 生成后事件

这篇文章为转载,作者比较在意别人对他文章的转载,转载地址为: http://blog.csdn.net/ydbcsdn/article/details/1817622 本文为原创,转载...
  • encoder1234
  • encoder1234
  • 2013年11月14日 17:15
  • 683

c# 命名空间、dll、与函数

命名空间与Main函数 namespace 是对类的封装,类似C++的namespace。C#中没有头文件与宏定义。 若将一个类Prog包含在命名空间A中,那么该类的完全限定名为A.Prog。 us...
  • chuchus
  • chuchus
  • 2014年07月18日 17:41
  • 1323

利用C++制作dll并调用dll

Abstract:本文讲解如何利用c++制作dll并调用dll,用一个简单的加法函数来作为演示,并给出图形界面。1. 打开vs(我用的是vs2010),然后点击文件—>文件—>新建—>项目,选择Win...
  • hlx371240
  • hlx371240
  • 2016年05月26日 15:58
  • 9834

Unity -VS - DLL 编辑后期生成事件

问题描述: 我有一个解决方案A_Project,还有另一个解决方案B_Project需要用到A的最新DLL,如果每次修改A_Project,然后复制最新的DLL到B_Project 很麻烦。 解决方...
  • u011473031
  • u011473031
  • 2016年08月19日 22:42
  • 1170

c++动态库加载顺序和同名动态库同时加载问题

本文仅 供学习参考,欢迎提出 宝贵意见 一,同名称动态库加载顺序。   现有同名称动态库Dllpath.dll 3个,内容非常简单,分别为 extern "C" __declspec(dllexpor...
  • mincheat
  • mincheat
  • 2016年05月04日 10:15
  • 2068

VS2012下如何生成和调用DLL

做工程的人都知道,代码编写是一个模块化的过程,有时候,其中一部分在其他的项目中也会使用,于是就会想着把这些编写成DLL,方便调用,于是花了一些时间了解了下DLL的相关信息。 1、DLL和LIB的联系区...
  • cwt19902010
  • cwt19902010
  • 2017年01月23日 10:23
  • 4113

VS2013环境生成和调用DLL动态链接库

创建动态库方法: 创建动态库是生成 .dll .lib 两个个文件 文件 -> 新建 -> 项目-> win32控制台应用程序 项目名称:DLLGenerator 应用程序类型:DLL ...
  • u010273652
  • u010273652
  • 2014年05月11日 00:43
  • 24173

matlab调用c++生成的DLL

最近项目测试出现一个令人头疼的问题,前面半个月基本都在修复程序内存泄露,利用一些内存泄露工具进行检测,检测的时候发现有些内存泄露并不完全能够根据行来定位,最好的办法,通过程序调试,在调式的过程执行到某...
  • ucas_123
  • ucas_123
  • 2016年07月18日 19:36
  • 935
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DLL实用技巧——namespace, 生成后事件
举报原因:
原因补充:

(最多只允许输入30个字)