2024年1月1日发(作者:)
生成解决方案以后为什么bin目录下没有dll文件呢?
篇一:DLL文件的生成和引用方法
一、 动态链接库
什么是动态链接库?DLL三个字母对于你来说一定很熟悉吧,它是Dynamic Link Library 的缩写形式,动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。
和大多数程序员一样,你一定很使用过DLL吧。也曾感受到它的带给你程序设计和编码
上的好错吧今天我想和大家探讨一个主题:如何在C#创建和调用DLL(动态链接库), 其实在很大意义上而讲,DLL让我更灵活的组织编写我们的应用程序,作为软件设计者, 1
可一个根据它来达到很高的代码重用效果。下面我来介绍一下在C#中如何创建和调用DLL。
二、准备工作
我们需要对我们接下来要做的事情做个简单的介绍,在本文我们将利用C#语言创建一个名为 的动态链接库,在这个动态链接库文件中我们将提供两个功能一个是对两个参数交换他们的值,另一个功能是求两个参数的最大公约数。然后创建一个应用程序使用这个DLL。运行并输出结果。
1、
namespace MyMethods
{
public class SwapClass
{
public static bool Swap(ref long i,ref long j)
{
i = i+j;
j = i-j;
i = i-j;
return true;
}
}
2
}
2、
namespace MyMethods
{
public class MaxCDClass
{
public static long MaxCD(long i, long j)
{
long a,b,temp;
if(ij)
{
a = i;
b = j;
}
else
{
b = i;
a = j;
}
temp = a % b;
while(temp!=0)
{
3
a = b;
b = temp;
temp = a % b;
}
return b;
}
}
}
需要注意的是:我们在制作这两个文件的时候可以用Visual 或者其他的文本编辑器,就算是记事本也可以。这两个文件虽然不在同一个文件里面,但是他们是属于同一个namespace(名称空间)这对以后我们使用这两个方法提供了方便。当然他们也可以属于不同的名称空间,这是完全可以的,但只是在我们应用他们的时候就需要引用两个不同的名称空间,所以作者建议还是写在一个名称空间下面比较好。
三、生成dll文件
有两种方法:
1:傻瓜式操作
打开VS2008,依次点击:菜单-文件-新建项目-项目类型visual C#(这里假设为该项目所取的名字是DllBuild)-类库(注意必须是类库),即新建一个由纯.cs类库文件组成的程序 4
集,写好代码之后(例如写了一个名为的类,该类的namespace取名为DllTestNS), 再依次点击:菜单-生成-生成DllBuild,这样你的DllBuild/DllBuild/bin/Debug文件夹或者 DllBuild/DllBuild/obj/Debug文件夹里便会自动生成dll文件啦,该文件名称与项目名称一致,即为。
2:使用VS命令行
“我的电脑”中搜索“”文件即可,比如我的文件便是在:
C:。为了不至于每次编译dll时都要输入如此长的VS命令行路径,我们可以将该路径添加到系统环境变量中。
然后点击“开始”-“运行”,输入:
csc /target:library /out: d: d:
d:
这样便直接进行编译。会在d盘生成
OK!我们创建动态链接库文件的任务完成了,现在是我们享受劳动成果的时候了,下面我将介绍如何使用我们所创建的动态链接库文件
四、使用DLL(测试)
现在我们重新新建一个模板类型为Console
Application(控制台应用程序)的项目,名为ConsoleApplication1, 新建好项目之后,从资源浏览器中 5
打开该项目,依次打开ConsoleApplication1ConsoleApplication1binDebug,将刚才生成的 文件复制到Debug目录下,然后用添加引用。
using MyMethods;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
long a = 4;
long b = 5;
(ref a, ref b);
(a={0} b={1}, a, b);
ne();
}
}
}
运行就可以看到可用了。
七、小结
动态链接具有下列优点:
6
1、节省内存和减少交换操作。很多进程可以同时使用一个 DLL,在内存中共享该 DLL 的一个副本。相反,对于每个用静态链接库生成的应用程序,Windows 必须在内存中加载库代码的一个副本。
2、节省磁盘空间。许多应用程序可在磁盘上共享 DLL
的一个副本。相反,每个用静
态链接库生成的应用程序均具有作为单独的副本链接到其可执行图像中的库代码。 3、升级到 DLL 更为容易。DLL 中的函数更改时,只要函数的参数和返回值没有更改,就不需重新编译或重新链接使用它们的应用程序。相反,静态链接的对象代码要求在函数更改时重新链接应用程序。
4、提供售后支持。例如,可修改显示器驱动程序 DLL 以支持当初交付应用程序时不可用的显示器。
5、支持多语言程序。只要程序遵循函数的调用约定,用不同编程语言编写的程序就可以调用相同的 DLL 函数。程序与 DLL 函数在下列方面必须是兼容的:函数期望其参数被推送到堆栈上的顺序,是函数还是应用程序负责清理堆栈,以及寄存器中是否传递了任何参数。 6、提供了扩展
MFC 库类的机制。可以从现有 MFC 类派生类,并将它们放到 MFC 扩
展 DLL 中供 MFC 应用程序使用。
7、使国际版本的创建轻松完成。通过将资源放到 DLL
7
中,创建应用程序的国际版本变得容易得多。可将用于应用程序的每个语言版本的字符串放到单独的 DLL 资源文件中,并使不同的语言版本加载合适的资源。
使用 DLL 的一个潜在缺点是应用程序不是独立的;它取决于是否存在单独的 DLL 模块。
篇二:DLL文件生成方法
DLL生成方法 供c#使用
1:打开vs2008,新建一个类库,名为Cmdll(C++.net语言)
2:在Cmdll.h中输入以下代码:
extern C __declspec(dllexport) int SampleMethod(int i)
{
return i*10;
}
3:编译一下,在项目的文件夹里会生成文件。这个就可以在c#中调用了。
c#调用如下
using System;
using pServices;
namespace ConsoleApplication1
{
class Program
{
8
[DllImport(, EntryPoint = SampleMethod)]
public static extern int SampleMethod(int x);
static void Main(string[] args)
{
ine(SampleMethod() returns {0}.,
SampleMethod(5));
();
}
}
}
C++ Dll 编写入门一、前言 自从微软推出16位的Windows操作系统起,此后每种版本的Windows操作系统都非常依赖于动态链接库(DLL)中的函数和数据,实际上Windows操作系统中几乎所有的内容都由DLL以一种或另外一种形式代表着,例如显示的字体和图标存储在GDI DLL中、显示Windows桌面和处理用户的输入所需要的代码被存储在一个User DLL中、Windows编程所需要的大量的API函数也被包含在Kernel DLL中。 在Windows操作系统中使用DLL有很多优点,最主要的一点是多个应用程序、甚至是不同语言编写的应用程序可以共享一个DLL文件,真正实现了资源共享,大大缩小了应用程序的执行代码,更加有效的利用了内存;使用DLL的另一个优点是DLL文件 9
作为一个单独的程序模块,封装性、独立性好,在软件需要升级的时候,开发人员只需要修改相应的DLL文件就可以了,而且,当DLL中的函数改变后,只要不是参数的改变,程序代码并不需要重新编译。这在编程时十分有用,大大提高了软件开发和维护的效率。 既然DLL那么重要,所以搞清楚什么是DLL、如何在Windows操作系统中开发使用DLL是程序开发人员不得不解决的一个问题。本文针对这些问题,通过一个简单的例子,即在一个DLL中实现比较最大、最小整数这两个简单函数,全面地解析了在Visual C++编译环境下编程实现DLL的过程,文章中所用到的程序代码在Windows98系统、Visual C++6.0编译环境下通过。 二、DLL的概念 DLL是建立在客户/服务器通信的概念上,包含若干函数、类或资源的库文件,函数和数据被存储在一个DLL(服务器)上并由一个或多个客户导出而使用,这些客户可以是应用程序或者是其它的DLL。DLL库不同于静态库,在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.LIB), Visual C++的编译器在处理程序代码时将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为静态链接,此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。 在动态库的情况下,有两个文件,一个是引入库(.LIB) 10
文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。 微软的Visual C++支持三种DLL,它们分别是Non-MFC Dll(非MFC动态库)、Regular Dll(常规DLL)、Extension Dll(扩展DLL)。Non-MFC DLL指的是不用MFC的类库结构,直接用C语言写的DLL,其导出的函数是标准的C接口,能被非MFC或MFC编写的应用程序所调用。Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的,它的一个明
显的特点是在源文件里有一个继承CWinApp的类(注意:此类DLL虽然从CWinApp派生,但没有消息循环),被导出的函数是C函数、C++类或者C++成员函数(注意不要把术语C++类与MFC的微软基础C++类相混淆),调用常规DLL的应用程序不必是MFC应用程序,只要是能调用类C函数的应用程序就可以,它们可以是在Visual C++、 11
Dephi、Visual Basic、Borland C等编译环境下利用DLL开发应用程序。 常规DLL又可细分成静态链接到MFC和动态链接到MFC上的,这两种常规DLL的区别将在下面介绍。与常规DLL相比,使用扩展DLL用于导出增强MFC基础类的函数或子类,用这种类型的动态链接库,可以用来输出一个从MFC所继承下来的类。 扩展DLL是使用MFC的动态链接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。例如你已经创建了一个从MFC的CtoolBar类的派生类用于创建一个新的工具栏,为了导出这个类,你必须把它放到一个MFC扩展的DLL中。扩展DLL
和
常规DLL不一样,它没有一个从CWinApp继承而来的类的对象,所以,开发人员必须在DLL中的DllMain函数添加初始化代码和结束代码。三、动态链接库的创建 在Visual
C++6.0开发环境下,打开FileNewProject选项,可以选择Win32 Dynamic-Link Library或MFC AppWizard[dll]来以不同的方式来创建Non-MFC Dll、Regular Dll、Extension Dll等不同种类的动态链接库。 1. Win32 Dynamic-Link
Library方式创建Non-MFC DLL动态链接库 每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,必须有一个WINMAIN函数一样。在Non-MFC DLL中DllMain是一个缺省的入口函数,你不需要编写自己的DLL 12
入口函数,用这个缺省的入口函数就能使动态链接库被调用时得到正确的初始化。如果应用程序的DLL需要分配额外的内存或资源时,或者说需要对每个进程或线程初始化和清除操作时,需要在相应的DLL工程的.CPP文件中对DllMain
()函数按照下面的格式书写。BOOL APIENTRY
DllMain(HANDLE
ul_reason_for_call,LPVOID
{switch( ul_reason_for_call
.......
.......
.......
)
hModule,DWORD
lpReserved)
{case
case
case
case
DLL_PROCESS_ATTACH:
DLL_THREAD_ATTACH:
DLL_THREAD_DETACH:
DLL_PROCESS_DETACH: .......}return TRUE; } 参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);
ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH:
DLL_THREAD_ATTACH:
DLL_PROCESS_DETACH:
进线进程程程被被被调调停用用止、、、DLL_THREAD_DETACH: 线程被停止;lpReserved为保留参数。到此为止,DLL的入口函数已经写了,剩下部分的实 13
现也不难,你可以在DLL工程中加入你所想要输出的函数或变量了。 我们已经知道DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义文件.Def。需要读者注意的是在使用第一种方法的时候,不能使用DEF文件。下面通过两个例子来说明如何使用这两种方法创建DLL文件。 1)使用导出函数关键字_declspec(dllexport)创建,该动态链接库中有两个函数,分别用来实现得到两个数的最大和最小数。在MyDll.h和文件中分别输入如下原代码: //MyDLL.h extern C
_declspec(dllexport) int Max(int a, int b); extern C
_declspec(dllexport) int Min(int a, int b); //
#include #includeMyDll.h int Max(int a, int b)
{if(a=b)return a; else return b; }int Min(int a, int b)
{if(a=b)return b; else return a; } 该动态链接库编译成功后,打开MyDll工程中的debug目录,可以看到、两个文件。LIB文件中包含DLL 文件名和DLL文件中的函数名等,该LIB文件只是对应该DLL文件的映像文件,与DLL文件中,LIB文件的长度要小的多,在进行隐式链接DLL时要用到它。读者可能已经注意到在 14
MyDll.h中有关键字extern C,它可以使其他编程语言访问你编写的DLL中的函数。 2)用.def文件创建工程MyDll 为了用.def文件创建DLL,请先删除上个例子创建的工程中的MyDll.h文件,保留并在该文件头删除#include
MyDll.h语句,同时往该工程中加入一个文本文件,命名为,再在该文件中加入如下代码: LIBRARY MyDll
//注意这里的MyDll是工程名如果不同则应用程序连接库时会发生连接错误EXPORTS Max @1, Min @2, 其中LIBRARY语句说明该def文件是属于相应DLL的,EXPORTS语句下列出要导出的函数名称。我们可以在.def文件中的导出函数后加@n,如Max@1,Min@2,表示要导出的函数顺序号,在进行显式连时可以用到它。该DLL编译成功后,打开工程中的Debug目录,同样也会看到和文件。 2.MFC AppWizard[dll]方式生成常规/扩展DLL 在MFC AppWizard[dll]下生成DLL文件又有三种方式,在创建DLL是,要根据实际情况选择创建DLL的方式。一种是常规DLL静态链接到MFC, 另一种是常规DLL动态链接到MFC。两者的区别是:前者使用的是MFC的静态链接库,生成的DLL文件长度大,一般不使用这种方
式,后者使用MFC的动态链接库,生成的DLL文件长度小;动态链接到MFC的规则DLL所有输出的函数应该以如 15
下语句开始:
AFX_MANAGE_STATE(AfxGetStaticModuleState( )) //此语句用来正确地切换MFC模块状态 最后一种是MFC扩展DLL,这种DLL特点是用来建立MFC的派生类,Dll只被用MFC类库所编写的应用程序所调用。前面我们已经介绍过, Extension DLLs 和Regular DLLs不一样,它没有一个从CWinApp继承而来的类的对象,编译器默认了一个DLL入口函数DLLMain()作为对DLL的初始化,你可以在此函数中实现初始化,代码如下: BOOL WINAPI
APIENTRY DLLMain(HINSTANCE hinstDll,DWORD
reason ,LPVOID flmpload) {switch(reason){……………//初始化代码; }return true; } 参数hinstDll存放DLL的句柄,参数reason指明调用函数的原因,lpReserved是一个被系统所保留的参数。对于隐式链接是一个非零值,对于显式链接值是零。 在MFC下建立DLL文件,会自动生成def文件框架,其它与建立传统的Non-MFC DLL没有什么区别,只要在相应的头文件写入关键字_declspec(dllexport)函数类型和函数名等,或在生成的def文件中EXPORTS 下输入函数名就可以了。需要注意的是在向其它开发人员分发MFC扩展DLL 时,不要忘记提供描述DLL中类的头文件以及相应的.LIB文件和DLL本身,此后开发人员就能充分利用你开发的扩展DLL了。四、动态链接库DLL的链接 应 16
用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。Visual C++6.0在VCbin目录下提供了一个名为的小程序,用它可以查看DLL文件中的函数结构。另外,Windows系统将遵循下面的搜索顺序来定位DLL: 1.包含EXE文件的目录,2.进程的当前工作目录,
3.Windows系统目录,
4.Windows目录,5.列在Path环境变量中的一系列目录。 1.隐式链接 隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec (dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用库中的Min函数。首先生成一个项目为TestDll,在DllTest.h、文件中分别输入如下代码:
//Dlltest.h #pragma comment(lib,) extern
C_declspec(dllimport) int Max(int a,int b); extern
C_declspec(dllimport) int Min(int a,int b); //
#include #includeDlltest.h void main() {int a; a=min(8,10)
printf(比较的结果为%dn,a); }//注意如果程序发生连接错误则要把lib文件加要工程里去在创建文件之前,要先将和拷贝到当前工程所在的目录下面,也可以拷贝到windows的System目录下。如果DLL使 17
用的是def文件,要删除TestDll.h文件中关键字extern C。TestDll.h文件中的关键字Progam commit是要Visual C+的编译器在link时,链接到文件,当然,开发人员也可以不使用#pragma comment(lib,)语句,而直接在工程的Setting-Link页的Object/Moduls栏填入既可。 2.显式链接 显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。下面是通过显式链接调用DLL中的Max函数的例子。#include #include void
main(void) {typedef int(*pMax)(int a,int b); typedef
int(*pMin)(int a,int b); HINSTANCE hDLL; PMax Max
HDLL=LoadLibrary();//加载动态链接库文件; Max=(pMax)GetProcAddress(hDLL,Max);
A=Max(5,8); Printf(比较的结果为%dn,a);
18
FreeLibrary(hDLL);//卸载文件; } 在上例中使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针,然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄,然后通过GetProcAddress()函数获取导入
到应用程序中的函数指针,函数调用完毕后,使用FreeLibrary()卸载DLL文件。在编译程序之前,首先要将DLL文件拷贝到工程所在的目录或Windows系统目录下。
使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,Min)改为GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。 本文通过通俗易懂的方式,全面介绍了动态链接库的概念、动态链接库的创建和动态链接库的链接,并给出个简单明了的例子,相信读者看了本文后,能够创建自己的动态链接库并应用到后续的软件开发当中去了,当然,读者要熟练操作DLL,还需要在大量的实践中不断摸索,希望本文能起到抛砖引玉的作用。
篇三:vs2010生成Dll文件并引用dll
19
vs2010生成Dll文件并引用dll(C#)
(2011-12-26 11:19:12)
转载▼
标签: 分类: 编程
vs2010
c
dll
引用
杂谈
1、创建新C#控制台应用程序,项目命名createBll,打开重命名为TestA(可以不重命名)并修改代码,如图:
写好后,可以写其它的类.cs文件
2、完成后,点击菜单栏的“项目”,下拉单选择“createDll属性”,打开如图窗口
在输出类型选择“类库”,然后关掉该窗口,生成解决方案,即生成了文件,在项目下目录下。
3、引用Dll文件,新建项目referenceDll,把上面生成的文件复制粘贴到新项目下Debug文件夹下面
4、在referenceDll项目解决方案处的引用点击右键,弹出窗口
20
浏览标签下,打开referenceDll项目下Debug文件,找到刚才复制过来的文件,单击确定即可引用。
5、双击引用下的createBll打开对象浏览器,展开可以看的文件里封装的方法TestA
6、编写Program里的相应代码
21


发布评论