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实用技巧——namespace, 生成后事件

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

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

DLL实用技巧——namespace, 生成后事件  本人不才, 暂时写不出什么好文,   今天, 我想在这里写一点我认为比较实用的技巧。在项目稍微大点的时候,我们不可避免得要把某些功能模块分开来进行...
  • tuwen
  • tuwen
  • 2007年11月03日 20:27
  • 2874

使用VS的生成事件命令行指令将生成的exe,dll文件复制到指定文件夹中

VS预生成事件命令行 和 生成后事件命令行 宏说明 $(ConfigurationName)            当前项目配置的名称(例如,“Debug|Any CPU”)。 $(Ou...
  • qq798833488
  • qq798833488
  • 2016年09月28日 14:15
  • 3204

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

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

Visual Studio如何生成事件自动拷贝文件到生成目录里(半转载)

$(ConfigurationName)           当前项目配置的名称(例如,“Debug|Any CPU”)。 $(OutDir)                            ...
  • jiachunfeng
  • jiachunfeng
  • 2015年11月24日 10:00
  • 4908

Delphi2005学习笔记4——再谈NameSpace和Dll以及Package

今天在BDN中看到一篇文章http://bdn.borland.com/article/0,1410,32765,00.html重要的部分摘抄如下Executive Summary•         ...
  • shidongdong
  • shidongdong
  • 2004年12月06日 22:37
  • 1493

C#项目的生成事件及批处理文件

一个C#项目,如果为同一个解决方案的其他项目所引用,则其编译后,会将DLL拷贝到引用项目中;但如果它并不被其他项目引用,但又想编译后能够自动将生成的东西拷贝过去,可以在项目的生成事件中,写上一些批处理...
  • leftfist
  • leftfist
  • 2015年02月05日 22:07
  • 3179

利用预生成事件修改dll的修定版本号

1.在预生成命令行中的添加命令行 $(TargetDir)Tools\sv2as $(ProjectDir)Properties\AssemblyInfo.cs 其中sv2as是一个exe ,可以...
  • tian_jinping
  • tian_jinping
  • 2013年05月29日 18:35
  • 1372

VS2008生成后事件设置

生成后事件,就是项目编译生成成功后执行的事件,通常的动作是将生成的dll,lib或者头文件拷贝到指定是目录下,而不用自己手动拷贝,非常的方便:下面是几个例子:copy /b "$(InputDir)D...
  • zipper9527
  • zipper9527
  • 2010年11月21日 22:20
  • 5535

VS生成后事件闲谈

之前写DirectX时,每次都是将shader编译后生成的文件放在$(ProjectDir)(ProjectDir) 然后再将生成的文件拷贝一份到$(OutDir)(OutDir)中,以便单独运行可...
  • u010897187
  • u010897187
  • 2015年04月13日 18:57
  • 1620
收藏助手
不良信息举报
您举报文章:DLL实用技巧——namespace, 生成后事件
举报原因:
原因补充:

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