[vip专享]C_中如何调用动态链接库DLL

合集下载

C语言创建动态dll和调用dll(visualstudio2013环境下)

C语言创建动态dll和调用dll(visualstudio2013环境下)

C语⾔创建动态dll和调⽤dll(visualstudio2013环境下)第⼀部分:创建动态dll库。

1、打开visual studio 创建⼀个控制台应⽤程序。

2、选择DLL,空项⽬。

3、点击源⽂件,创建⼀个main.c⽂件4、在main.c中写⼊⼀个简单的函数,内容如下:__declspec(dllexport)int mymax(int a,int b){return a + b;}5、编译⽣成。

6、在项⽬的⽬录有dll和lib两个⽣成好的⽂件。

第⼆部分:在新建项⽬中使⽤dll。

7、新建⼀个c的控制台应⽤程序UseDll,把Dll.dll放⼊Debug⽬录下。

8、把Dll.lib放⼊UserDll⽬录下。

9、在UseDll项⽬中新建⼀个源⽂件use.c,代码如下:#include<stdio.h>#pragma comment(lib,"Dll.lib")int mymax(int a,int b);int main(){printf("调⽤动态dll函数的结果:%d",mymax(5,6));getchar();return 0;}10、运⾏结果如下PS:vs2013调试程序时出现“计算机丢失.dll⽂件”在VS环境下能够编译成功,但是在运⾏.exe⽂件时,出现“计算机丢失xxx.dll⽂件”的提⽰的解决⽅式。

发⽣这种问题的根本原因在于环境变量的设置上,计算机只会在path下包含的⽬录⾥去寻找程序所要运⾏的.dll⽂件,若我们所要使⽤到的.dll⽂件没有包含在环境变量path中,则会发⽣错误:计算机丢失xxx.dll⽂件。

⼯具/原料1. VS2013或者其他版本2. VTK库或者其他库⽅法/步骤这⾥以丢失vtkIOPLY-7.0-gd.dll⽂件为例(主要是关于PCL1.8.0),找到VTK的安装⽬录下的bin⽂件夹(包含vtkIOPLY-7.0-gd.dll),我的bin⽂件夹是在C:\Program Files (x86)\PCL1.8.0\3rdParty\VTK\bin将上述⽬录添加到环境变量Path中,如下图所⽰重新开启项⽬,重新⽣成解决⽅案,则问题就会解决注意事项这⾥不仅仅是针对vtkIOPLY-7.0-gd.dll⽂件,任何丢失.dll⽂件都可以使⽤此⽅式解决以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

C#调用dll动态库方法

C#调用dll动态库方法

C#调用C++编写的COM DLL封装库时会出现两个问题:1.数据类型转换问题2.指针或地址参数传送问题首先是数据类型转换问题。

因为C#是.NET语言,利用的是.NET的基本数据类型,所以实际上是将C++的数据类型与.NET的基本数据类型进行对应。

例如C++的原有函数是:int __stdcall FunctionName(unsigned char param1, unsigned short param2) 其中的参数数据类型在C#中,必须转为对应的数据类型。

如:[DllImport(“ COM DLL path/file ”)]extern static int FunctionName(byte param1, ushort param2)因为调用的是__stdcall函数,所以使用了P/Invoke的调用方法。

其中的方法FunctionName必须声明为静态外部函数,即加上extern static声明头。

我们可以看到,在调用的过程中,unsigned char变为了byte,unsigned short变为了ushort。

变换后,参数的数据类型不变,只是声明方式必须改为.NET语言的规范。

我们可以通过下表来进行这种转换:之后再将CLR的数据类型表示方式转换为C#的表示方式。

这样一来,函数的参数类型问题就可以解决了。

现在,我们再来考虑下一个问题,如果要调用的函数参数是指针或是地址变量,怎么办?对于这种情况可以使用C#提供的非安全代码来进行解决,但是,毕竟是非托管代码,垃圾资源处理不好的话对应用程序是很不利的。

所以还是使用C#提供的ref以及out修饰字比较好。

同上面一样,我们也举一个例子:int __stdcall FunctionName(unsigned char &param1, unsigned char *param2)在C#中对其进行调用的方法是:[DllImport(“ COM DLL path/file ”)]extern static int FunctionName(ref byte param1, ref byte param2)看到这,可能有人会问,&是取地址,*是传送指针,为何都只用ref就可以了呢?一种可能的解释是ref是一个具有重载特性的修饰符,会自动识别是取地址还是传送指针。

VC中使用动态链接库DLL

VC中使用动态链接库DLL

VC中使用动态链接库DLL:静态调用和动态调用2010-05-02 15:56VC中生成DLL的办法见:/KB/DLL/RegDLL.aspx--------------------------------------VC中使用DLL/c1230v/articles/1401448.html调用DLL有两种方法:静态调用和动态调用.(一).静态调用其步骤如下:1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;2.把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;3.把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目录下;4.打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;5.执行第4步后,VC将会弹出一个对话框,在对话框的多页显示控件中选择Link页。

然后在Object/library modules输入框中输入:youApp.lib6.选择你的目标工程Head Files加入:youApp.h文件;7.最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include "youApp.h"注:youApp是你DLL的工程名。

(二).动态调用其程序如下:动态调用时只需做静态调用步骤1.01 {02 HINSTANCE hDllInst = LoadLibrary("youApp.DLL");03if(hDllInst)04 {05typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD);06 MYFUNC youFuntionNameAlias = NULL;07// youFuntionNameAlias 函数别名08 youFuntionNameAlias = (MYFUNC)GetProcAddress(hDllInst,"youFuntionName"); 09// youFuntionName 在DLL中声明的函数名10if(youFuntionNameAlias)11 {12 youFuntionNameAlias(param1,param2);13 }14 FreeLibrary(hDllInst);15 }16 }显式(静态)调用:LIB + DLL + .H,注意.H中dllexport改为dllimport隐式(动态)调用:DLL + 函数原型声明,先LoadLibrary,再GetProcAddress(即找到DLL中函数的地址),不用后FreeLibrary--------------------------------------动态链接库DLL的链接/mmycly/archive/2006/06/15/917076.aspx应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接。

总结的c#调用DLL方法

总结的c#调用DLL方法
The MaxCD of 456 and 123 is 3
小结:
动态链接具有下列优点:
节省内存和减少交换操作。很多进程可以同时使用一个DLL,在内存中共享该DLL的一个副本。相反,对于每个用静态链接库生成的应用程序,Windows必须在内存中加载库代码的一个副本。
节省磁盘空间。许多应用程序可在磁盘上共享DLL的一个副本。相反,每个用静态链接库生成的应用程序均具有作为单独的副本链接到其可执行图像中的库代码。
long maxcd = MaxCDClass.MaxCD(num1,num2);
Console.WriteLine("The MaxCD of {0} and {1} is {2}",num1, num2, maxcd);
}
}
若要生成可执行文件MyClient.exe,请使用以下命令行:
csc /out:MyClient.exe /reference:MyLibrary.DLL MyClient.cs
升级到DLL更为容易。DLL中的函数更改时,只要函数的参数和返回值没有更改,就不需重新编译或重新链接使用它们的应用程序。相反,静态链接的对象代码要求在函数更改时重新链接应用程序。
提供售后支持。例如,可修改显示器驱动程序DLL以支持当初交付应用程序时不可用的显示器。
支持多语言程序。只要程序遵循函数的调用约定,用不同编程语言编写的程序就可以调用相同的DLL函数。程序与DLL函数在下列方面必须是兼容的:函数期望其参数被推送到堆栈上的顺序,是函数还是应用程序负责清理堆栈,以及寄存器中是否传递了任何参数。
}
(3)在CS编辑器中再次添加一个CS文件,名字自取,但包函main入口函数,在这个文件中便可以引用C++写的DLL文件中的函数了

Windows下C语言调用dll动态链接库

Windows下C语言调用dll动态链接库

Windows下C语⾔调⽤dll动态链接库dll是windows下的动态链接库⽂件,下⾯记录⼀下在windows下如何调⽤C语⾔开发的dll动态链接库。

1.dll动态链接库的源代码hello_dll.c#include "stdio.h"_declspec(dllexport) void test_print(char const *str){printf("%s\n", str);}_declspec(dllexport) int test_add(int a, int b){return a + b;}上⾯的代码定义了两个函数,第⼀个函数需要传⼊⼀个字符串,然后打印出这个字符串,第⼆个函数需要转⼊两个int型整数,然后返回这两个整数的和。

执⾏ cl -LD hello_dll.c 会⽣成hello_dll.dll⽂件2.main函数的源代码test_hello_dll.c#include <stdlib.h>#include <windows.h>int main(int argc, char const *argv[]){// define two functional pointervoid(*p_test_print)(char const *) = NULL;int(*p_test_add)(int, int) = NULL;int add_result;// load dll file, require window.h fileHMODULE module = LoadLibraryA("hello_dll.dll");if (module == NULL) {system("error load");}p_test_print = (void(*)(char const *))GetProcAddress(module, "test_print");p_test_add = (int(*)(int, int))GetProcAddress(module, "test_add");if (p_test_print != NULL) {p_test_print("Hello This is from dll");} else {system("function p_test_print can not excute");}if (p_test_add != NULL) {add_result = p_test_add(5, 5);printf("Add result is %d\n", add_result);} else {system("function p_test_print can not excute");}FreeLibrary(module);system("pause");return0;}执⾏ cl test_hello_dll.c 会⽣成test_hello_dll.exe的可执⾏⽂件。

c#(winform)环境下使用动态链接库dll的详解

c#(winform)环境下使用动态链接库dll的详解

c#(winform)环境下使⽤动态链接库dll的详解1,什么是dll⽂件?DLL(Dynamic Link Library)⽂件为动态链接库⽂件,⼜称“应⽤程序拓展”,是软件⽂件类型。

在Windows中,许多应⽤程序并不是⼀个完整的,它们被分割成⼀些相对独⽴的,即DLL⽂件,放置于系统中。

当我们执⾏某⼀个时,相应的DLL⽂件就会被调⽤。

⼀个应⽤程序可使⽤多个DLL⽂件,⼀个DLL⽂件也可能被不同的应⽤程序使⽤,这样的DLL⽂件被称为共享DLL⽂件。

2,托管dll和⾮托管dll区别是什么?托管DLL就是能够在公共语⾔运⾏库(Common Language Runtime,简称CLR)中能够直接引⽤的,并且扩展为“DLL”的⽂件。

具体所指就是封装各种命名空间所在的DLL⽂件,如System.dll等。

⾮托管DLL就是平常所的动态链接库等,其中就包括了封装所有Windows API函数的DLL⽂件。

各种⾮托管DLL中的函数在公共语⾔运⾏库中不能直接被调⽤,⽽需要经过.Net框架提供的“平台调⽤”服务后才可以。

(简⽽⾔之就是.net环境下⽣成的动态链接库为托管dll,相反则为⾮托管dll)3,托管dll和⾮托管dll如何使⽤?托管dll在VS环境下使⽤相对容易,可以在项⽬名上右击选择添加应⽤的⽅式导⼊dll,本⽂这⾥不作详解。

⾮托管dll的使⽤步骤及如下:1,需要检查使⽤的dll的⽬标平台(Any Cpu,x86,x64),在项⽬属性⽣成选项卡中选择与dll相对应的⽬标平台。

因为托管dll是在.net的环境下⽣成的,转换为机器语⾔后能够⾃动识别⽬标平台即有框架⽀持解释,⽽⾮托管不能够⾃⼰识别需要⼈为的设置。

2,使⽤DllImport导⼊⾮托管dll。

DllImport会按照以下3种顺序查找dll⽂件:1)、exe所在⽬录;2)、System32⽬录(系统⽬录);3)、环境变量⽬录。

(即需要将dll及依赖⽂件放到3个⽬录中的任何⼀个⽬录中)。

Java调用C和C++动态链接库DLL第一步利用JNI

Java调用C/C++动态链接库DLL第一步利用JNI1.新建一个项目,创建一个类TestNative.java,然后点击run运行生成.class文件2.利用jdk自带的工具javah.exe 生成这个sayHello()这个native本地方法的头文件先进入eclipse下工程目录,进入bin目录,然后执行如下代码,编译出头文件这时候会出现一个自动生成的头文件用于我们编写C/C++代码3.利用Visual Studio2010 新建一个window控制台项目复制刚才利用javah生成的com_taobao_jni_TestNative.h到C++项目工程目录下,然后右击添加-->现有项将头文件引入到项目环境中4.添加JDK中系统头文件,如jni.h,这个头文件其实是在jdk目录下的include 目录下我们需要将jdk所需的所有头文件(包括win32下的所有头文件)复制到visual studio中VC 编译工具的include文件夹中,添加引入。

【所有头文件必须富之岛include的根目录下】这时候vs编译器就不会报错了,接下来我们新建一个NativeCode.cpp文件,复制生成的头文件里面的方法,实现此方法#include"com_taobao_jni_TestNative.h"#include<iostream>usingnamespace std;JNIEXPORT void JNICALL Java_com_taobao_jni_TestNative_sayHello (JNIEnv * env, jobjectobj) {cout<<"Hello World..."<<endl;}编译执行生成对应的dll文件,对与不同位数版本的jdk我们需要生成不同位数的dll,就如我的jdk是64位,那么我就需要编译出64位的dll,默认VS的编译指定是32bit,我们需要添加x64支持。

如何用VC创建及调用DLL

如何用VC创建及调用DLL使用Visual C++(VC++)创建和调用动态链接库(DLL)可以提供一种模块化的方式来组织和重用代码。

本文将介绍如何使用VC++创建DLL,并在另一个VC++项目中调用该DLL。

创建DLL以下是使用VC++创建DLL的步骤:1.打开VC++,在“文件”菜单中选择“新建”->“项目”。

2. 在“新建项目”对话框中,选择“Win32控制台应用程序”。

点击“下一步”。

3.输入项目名称,并选择项目位置,点击“下一步”。

4.在“应用程序类型”对话框中,选择“DLL”并取消勾选“预编译头”。

点击“下一步”。

5.在“进入代码”对话框中,选择“空项目”。

点击“完成”。

6. 创建一个新的源文件,例如“MyDLL.cpp”。

7. 在“MyDLL.cpp”中,编写所需的函数并导出。

例如:```C++#include <Windows.h>// 导出的函数需要使用__declspec(dllexport)修饰extern "C" __declspec(dllexport) int AddNumbers(int a, int b) return a + b;```8. 在项目属性中,选择“链接器”->“高级”,将“入口点”设置为“DllMain”。

9.在“生成”菜单中选择“生成解决方案”,以生成DLL文件。

以下是在VC++项目中调用DLL的步骤:1.打开VC++,在“文件”菜单中选择“新建”->“项目”。

2. 在“新建项目”对话框中,选择“Win32控制台应用程序”。

点击“下一步”。

3.输入项目名称,并选择项目位置,点击“下一步”。

4.在“应用程序类型”对话框中,选择“控制台应用程序”并取消勾选“预编译头”。

点击“下一步”。

5.在“附加选项”对话框中,勾选“空项目”。

点击“完成”。

6.将之前生成的DLL文件复制到新项目的文件夹中。

7.在项目属性中,选择“C/C++”->“常规”,将“附加包含目录”设置为包含DLL文件的文件夹路径。

MFC创建动态链接库DLL并调用方法详解

MFC创建动态链接库DLL并调⽤⽅法详解实例⼀:1、创建⼀个动态链接库⼯程,如login_dll。

2、在原⼯程头⽂件或者新建头⽂件如showdlg.h定义动态链接库的导出函数,代码如下:#include "stdafx.h"#define EXPORT __declspec(dllexport)extern "C" EXPORT void __stdcall Showdialg(char* pText);3、在动态链接库源⽂件中定义showdialog函数,代码如下:void _stdcall Showdialg(char* pText){MessageBox(NULL,pText,"提⽰⼀",0);}注:此步编译后,即可⽣成dll与lib⽂件,因为_stdcall是⼀种⽐较流⾏的函数调⽤约定,(或者可以不⽤_stdcall),如果使⽤的时候,为了防⽌发⽣函数命令改编的情况,可以定义⼀个.def⽂件,其中加⼊EXPORTS节,设置导出函数名,如下所⽰:LIBRARY "login_dll"EXPORTSShowdialg = Showdialg4、创建⼀个基于对话框的⼯程。

5、定义⼀个函数指针类型,其定义与动态链接库的函数原型相同,代码如下:typedef void (__stdcall * funShowInfo)(char* pchData);6、处理按键单击事件,加载动态链接库,代码如下:void Cuse_login_dllDlg::OnBnClickedOk(){HMODULE hMod = LoadLibrary("login_dll.dll");if (hMod != NULL){funShowInfo ShowInfo;ShowInfo = (funShowInfo)GetProcAddress(hMod,"Showdialg");if (ShowInfo)ShowInfo("传⼊参数成功且调⽤正常");}FreeLibrary(hMod);}其中,第5步与第6步是通过LoadLibrary函数动态加载链接库的⽅法,下⾯介绍⼀下静态加载链接库的⽅法:1、加载链接库的头⽂件,将动态链接库头⽂件拷贝到当前⼯程中,并在当前⼯程头⽂件进⾏声明。

C动态链接库的函数和使用方法

C动态链接库的函数和使用方法动态链接库(Dynamic Link Library,简称DLL)是Windows操作系统中一种常用的库文件格式,它包含了一系列的函数和数据,可以供其他程序调用。

相对于静态链接库(静态库),动态链接库具有一些独特的特点和优势。

一、函数和使用方法:1.创建动态链接库:在Windows操作系统上,可以使用多种开发工具来创建动态链接库,最常用的是使用C/C++语言结合相应的集成开发环境(IDE)来进行创建。

下面以Visual Studio为例,介绍创建动态链接库的方法。

a) 打开Visual Studio,选择“新项目” -> “Win32控制台应用程序”。

b)在向导中选择“下一步”,然后选择“DLL”,并输入项目名称。

c)设定项目的相关属性,如生成目标、包含的文件等。

d)完成创建,并在项目中编写所需的函数和代码。

2.导出函数:在创建动态链接库的过程中,需要显式地将要调用的函数导出。

导出函数的方法有多种,其中最常用的是使用extern关键字和declspec属性。

a) 使用extern关键字:```extern "C" _declspec(dllexport) int myFunction(int param);```这样可以将myFunction函数导出,使其可以供其他程序调用。

b) 使用declspec属性:```#ifdef MYDLL_EXPORTS#define MYDLL_API _declspec(dllexport)#else#define MYDLL_API _declspec(dllimport)#endifMYDLL_API int myFunction(int param);```这样可以根据是否定义了MYDLL_EXPORTS宏来自动切换函数的导入导出。

3.调用动态链接库中的函数:在其他程序中使用动态链接库的函数需要进行动态链接,将DLL加载到内存中,并获取相应的函数指针进行调用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C#中如何调用动态链接库DLL动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL 文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。

动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。

注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。

DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。

在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。

DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。

下面列出了当程序使用 DLL 时提供的一些优点:[1]1) 使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。

这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。

2) 推广模块式体系结构DLL 有助于促进模块式程序的开发。

这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。

模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。

3) 简化部署和安装当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。

此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。

当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。

每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍。

首先,您需要了解什么是托管,什么是非托管。

一般可以认为:非托管代码主要是基于win 32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。

如果您想深入了解托管与非托管的关系与区别,及它们的运行机制,请您自行查找资料,本文件在此不作讨论。

(一) 调用DLL中的非托管函数一般方法首先,应该在C#语言源程序中声明外部方法,其基本形式是:[DLLImport(“DLL文件”)]修饰符 extern 返回变量类型方法名称(参数列表)其中:DLL文件:包含定义外部方法的库文件。

修饰符:访问修饰符,除了abstract以外在声明方法时可以使用的修饰符。

返回变量类型:在DLL文件中你需调用方法的返回变量类型。

方法名称:在DLL文件中你需调用方法的名称。

参数列表:在DLL文件中你需调用方法的列表。

注意:需要在程序声明中使用System.Runtime.InteropServices命名空间。

DllImport只能放置在方法声明上。

DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。

返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。

若要使用其它函数名,可以使用EntryPoint属性设置,如:[DllImport("user32.dll", EntryPoint="MessageBoxA")]static extern int MsgBox(int hWnd, string msg, string caption, int type);其它可选的 DllImportAttribute 属性:CharSet 指示用在入口点中的字符集,如:CharSet=CharSet.Ansi;SetLastError 指示方法是否保留 Win32"上一错误",如:SetLastError=true;ExactSpelling 指示EntryPoint 是否必须与指示的入口点的拼写完全匹配,如:ExactSpelling=false;PreserveSig指示方法的签名应当被保留还是被转换,如:PreserveSig=true;CallingConvention指示入口点的调用约定,如:CallingConvention=CallingConvention.Winapi;此外,关于“数据封送处理”及“封送数字和逻辑标量”请参阅其它一些文章[2]。

C#例子:1. 启动,新建一个项目,项目名称为“Tzb”,模板为“Windows 应用程序”。

2. 在“工具箱”的“ Windows 窗体”项中双击“Button”项,向“Form1”窗体中添加一个按钮。

3. 改变按钮的属性:Name为“B1”,Text为“用DllImport调用DLL弹出提示框”,并将按钮B1调整到适当大小,移到适当位置。

4. 在类视图中双击“Form1”,打开“Form1.cs”代码视图,在“namespace Tzb”上面输入“using System.Runtime.InteropServices;”,以导入该命名空间。

5. 在“Form1.cs[设计]”视图中双击按钮B1,在“B1_Click”方法上面使用关键字 static 和 extern 声明方法“MsgBox”,将 DllImport 属性附加到该方法,这里我们要使用的是“user32.dll”中的“MessageBoxA”函数,具体代码如下:[DllImport("user32.dll", EntryPoint="MessageBoxA")]static extern int MsgBox(int hWnd, string msg, string caption, int type);然后在“B1_Click”方法体内添加如下代码,以调用方法“MsgBox”:MsgBox(0," 这就是用 DllImport 调用 DLL 弹出的提示框哦! "," 挑战杯 ",0x30);6. 按“F5”运行该程序,并点击按钮B1,便弹出如下提示框:(二) 动态装载、调用DLL中的非托管函数在上面已经说明了如何用DllImport调用DLL中的非托管函数,但是这个是全局的函数,假若DLL中的非托管函数有一个静态变量S,每次调用这个函数的时候,静态变量S就自动加1。

结果,当需要重新计数时,就不能得出想要的结果。

下面将用例子说明:1. DLL的创建1) 启动Visual C++ 6.0;2) 新建一个“Win32 Dynamic-Link Library”工程,工程名称为“Count”;3) 在“Dll kind”选择界面中选择“A simple dll project”;4) 打开Count.cpp,添加如下代码:// 导出函数,使用“ _stdcall ” 标准调用extern "C" _declspec(dllexport)int _stdcall count(int init);int _stdcall count(int init){//count 函数,使用参数 init 初始化静态的整形变量 S ,并使 S 自加 1 后返回该值static int S=init;S++;return S;}5) 按“F7”进行编译,得到Count.dll(在工程目录下的Debug文件夹中)。

2. 用DllImport调用DLL中的count函数1) 打开项目“Tzb”,向“Form1”窗体中添加一个按钮。

2) 改变按钮的属性:Name为 “B2”,Text为 “用DllImport调用DLL中count 函数”,并将按钮B1调整到适当大小,移到适当位置。

3) 打开“Form1.cs”代码视图,使用关键字static 和extern 声明方法“count”,并使其具有来自 Count.dll 的导出函数count的实现,代码如下:[DllImport("Count.dll")]static extern int count(int init);4) 在“Form1.cs[设计]”视图中双击按钮B2,在“B2_Click”方法体内添加如下代码:MessageBox.Show(" 用 DllImport 调用 DLL 中的 count 函数, n 传入的实参为 0 ,得到的结果是: "+count(0).ToString()," 挑战杯 ");MessageBox.Show(" 用 DllImport 调用 DLL 中的 count 函数, n 传入的实参为 10 ,得到的结果是: "+count(10).ToString()+"n 结果可不是想要的 11 哦!!! "," 挑战杯 ");MessageBox.Show(" 所得结果表明: n 用 DllImport 调用 DLL 中的非托管 n 函数是全局的、静态的函数!!! "," 挑战杯 ");5) 把Count.dll复制到项目“Tzb”的binDebug文件夹中,按“F5”运行该程序,并点击按钮B2,便弹出如下三个提示框:第1个提示框显示的是调用“count(0)”的结果,第2个提示框显示的是调用“count(10)”的结果,由所得结果可以证明“用DllImport调用DLL中的非托管函数是全局的、静态的函数”。

所以,有时候并不能达到我们目的,因此我们需要使用下面所介绍的方法:C#动态调用DLL中的函数。

3. C#动态调用DLL中的函数因为C#中使用DllImport是不能像动态load/unload assembly那样,所以只能借助API函数了。

在kernel32.dll中,与动态库调用有关的函数包括[3]:①LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。

②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。

它们的原型分别是:HMODULE LoadLibrary(LPCTSTR lpFileName);FARPROC GetProcAddress(HMODULE hModule, LPCWSTR lpProcName);BOOL FreeLibrary(HMODULE hModule);现在,我们可以用IntPtr hModule=LoadLibrary(“Count.dll”);来获得Dll的句柄,用IntPtr farProc=GetProcAddress(hModule,”_count@4”);来获得函数的入口地址。

相关文档
最新文档