版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C#调用外部dll一、DLL与应用程序动态链接库(也称为DLL,即为“DynamicLinkLibrary”的缩写)是MicrosoftWindows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。注:C#中一般称为方法”)但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进
2、程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。下面列岀了当程序使用DLL时提供的一些优点:11)使用较少的资源当多个程序使用同一个函数库时,DLL可以减少在磁盘和物理内存中加载的代码的重复量。这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在Windows操作系统上运行的程序。2)推广模块式体系结构DLL有助于促进模块式程序
3、的开发。这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。3)简化部署和安装当DLL中的函数需要更新或修复时,部署和安装DLL不要求重新建立程序与该DLL的链接。此外,如果多个程序使用同一个DLL,那么多个程序都将从该更新或修复中获益。当您使用定期更新或修复的第三方DLL时,此问题可能会更频繁地岀现。二、DLL的调用每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍。首先,您需要了解什么是托管,什么是非托管。一般可以认为:非托管代码主要是基于win32平台开发的DLL,a
4、ctiveX的组件,托管代码是基于.net平台开发的。如果您想深入了解托管与非托管的关系与区别,及它们的运行机制,请您自行查找资料,本文件在此不作讨论。(一)调用DLL中的非托管函数一般方法首先,应该在C#语言源程序中声明外部方法,其基本形式是:DLLImport(“DL文件”)修饰符extern返回变量类型方法名称(参数列表)其中:DLL文件:包含定义外部方法的库文件。修饰符:访问修饰符,除了abstract以外在声明方法时可以使用的修饰符。返回变量类型:在DLL文件中你需调用方法的返回变量类型。方法名称:在DLL文件中你需调用方法的名称。参数列表:在DLL文件中你需调用方法的列表。注意:需
5、要在程序声明中使用System.Runtime.lnteropServices命名空间。Dlllmport只能放置在方法声明上。DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。若要使用其它函数名,可以使用EntryPoint属性设置,如:Dlllmport("user32.dll",EntryPoint="MessageBoxA")staticexternintMsgBox(inthWnd,stringmsg,stringcaption,in
6、ttype);其它可选的DllImportAttribute属性:CharSet指示用在入口点中的字符集,如:CharSet=CharSet.Ansi;SetLastError指示方法是否保留Win32"上一错误",如:SetLastError=true;ExactSpelling指示EntryPoint是否必须与指示的入口点的拼写完全匹配,如:ExactSpelling=false;PreserveSig指示方法的签名应当被保留还是被转换,女口:PreserveSig=true;CallingConvention指示入口点的调用约定,女口:CallingConventio
7、n=CallingConvention.Winapi;此外,关于数据封送处理”及封送数字和逻辑标量”请参阅其它一些文章2。C#例子:1. 启动VS.NET,新建一个项目项目名称为“Tzb,”模板为“Windows应用程序”2. 在工具箱"的“Windows窗体"项中双击“Button项,向“Form1窗体中添加一个按钮。3. 改变按钮的属性:Name为“B1:Text为用DllImport调用DLL弹岀提示框”并将按钮B1调整到适当大小,移到适当位置。4. 在类视图中双击“Form1,打开“Form1.cs”弋码视图,在“namespaceTzb上面输入“usingSyst
8、em.Runtime.lnteropServices;,以导入该命名空间。5. 在“Form1.cs设计"视图中双击按钮B1,在“B1_Click方法上面使用关键字static和extern声明方法“MsgBox:将DllImport属性附加到该方法,这里我们要使用的是“user32.dll中的“MessageBoxA函数,具体代码如下:DllImport("user32.dll",EntryPoint="MessageBoxA")staticexternintMsgBox(inthWnd,stringmsg,stringcaption,int
9、type);然后在“B1_Click:方法体内添加如下代码,以调用方法“MsgBox:MsgBox(0,"这就是用DllImport调用DLL弹岀的提示框哦!",“挑战杯",0x30);6. 按“F5运行该程序,并点击按钮B1,便弹岀如下提示框:|这就显用Dlllport调用D曲出的提示框峨,(二) 动态装载、调用DLL中的非托管函数在上面已经说明了如何用Dlllmport调用DLL中的非托管函数,但是这个是全局的函数,假若DLL中的非托管函数有一个静态变量S,每次调用这个函数的时候,静态变量S就自动加1。结果,当需要重新计数时,就不能得岀想要的结果。下面将用例子
10、说明:1. DLL的创建1) 启动VisualC+6.0;2) 新建一个“Win32Dynamic-LinkLibrary工程,工程名称为“Count;3) 在“Dllkind选择界面中选择“Asimpledllproject;”4) 打开Count.cpp,添加如下代码:/导岀函数,使用“_stdcall标准调用extern"C"_declspec(dllexport)int_stdcallcount(intinit);int_stdcallcount(intinit)/count函数,使用参数init初始化静态的整形变量S,并使S自加1后返回该值staticintS=i
11、nit;S+;returnS;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(&quo
12、t;Count.dll")staticexternintcount(intinit);4) 在“Form1.cs设计"视图中双击按钮B2,在“B2_Click方法体内添加如下代码:MessageBox.Show(”用Dlllmport调用DLL中的count函数,n传入的实参为0,得到的结果是:"+count(O).ToString(),"挑战杯“);MessageBox.Show(”用DllImport调用DLL中的count函数,n传入的实参为10,得到的结果是:"+count(10).ToString()+"n结果可不是想要的1
13、1哦!",“挑战杯“);MessageBox.Show(”所得结果表明:n用DllImport调用DLL中的非托管n函数是全局的、静态的函数!",“挑战杯“);5)把Count.dll复制到项目“Tzb的binDebug文件夹中,按“F5运行该程序,并点击按钮B2,便弹出如下三个提示框:第1个提示框显示的是调用“count(0)"的结果,第2个提示框显示的是调用“count(10)”踣累可术是想娶的M哦?*I;殛的结果,由所得结果可以证明用DllImport调用DLL中的非托管函数是全局的、静态的函数”。所以,有时候并不能达到我们目的,因此我们需要使用下面所介绍的
14、方法:C#动态调用DLL中的函数。3.C#动态调用DLL中的函数因为C#中使用DllImport是不能像动态load/unloadassembly那样,所以只能借助API函数了。在kernel32.dll中,与动态库调用有关的函数包括3: LoadLibrary(或MFC的AfxLoadLibrary),装载动态库。 GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。 FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。它们的原型分别是:HMODULELoadLibrary(LPCTSTRlpFileName);FARPROCG
15、etProcAddress(HMODULEhModule,LPCWSTRlpProcName);BOOLFreeLibrary(HMODULEhModule);现在,我们可以用IntPtrhModule=LoadLibrary(“Count.dll”);来获得Dll的句柄,用IntPtrfarProc=GetProcAddress(hModule,”_count4”);来获得函数的入口地址。但是,知道函数的入口地址后,怎样调用这个函数呢?因为在C#中是没有函数指针的,没有像C+那样的函数指针调用方式来调用函数,所以我们得借助其它方法。经过研究,发现我们可以通过结合使用System.Reflec
16、tion.Emit及System.Reflection.Assembly里的类和函数达至U我们的目的。为了以后使用方便及实现代码的复用,我们可以编写一个类。1)dld类的编写:1. 打开项目“Tzb,"打开类视图,右击“Tzb,"选择添加"->“类",类名设置为“dld,"即dynamicloadingdll的每个单词的开头字母。2. 添加所需的命名空间及声明参数传递方式枚举:usingSystem.Runtime.lnteropServices;/用DllImport需用此命名空间usingSystem.Reflection;/使用As
17、sembly类需用此命名空间usingSystem.Reflection.Emit;/使用ILGenerator需用此命名空间在“publicclassdld上面添加如下代码声明参数传递方式枚举:/<summary>/参数传递方式枚举,ByValue表示值传递,ByRef表示址传递/</summary>publicenumModePassByValue=0x0001,ByRef=0x00023. 声明LoadLibrary、GetProcAddress、FreeLibrary及私有变量hModule和farProc:/<summary>/原型是:HMODUL
18、ELoadLibrary(LPCTSTRlpFileName);/</summary>/<paramname="lpFileName">DLL文件名</param>/<returns>函数库模块的句柄</returns>Dlllmport("kernel32.dll")staticexternIntPtrLoadLibrary(stringlpFileName);/<summary>/原型是:FARPROCGetProcAddress(HMODULEhModule,LPCWSTRIp
19、ProcName);III</summary>III<paramname="hModuIe">包含需调用函数的函数库模块的句柄<Iparam>IIIvparamname="IpProcName">调用函数的名称<Iparam>III<returns>函数指针vIreturns>Dlllmport("kernel32.dll")staticexternIntPtrGetProcAddress(lntPtrhModule,stringlpProcName);III&l
20、t;summary>III原型是:BOOLFreeLibrary(HMODULEhModule);III<Isummary>IIIvparamname="hModule">需释放的函数库模块的句柄<Iparam>III<returns>是否已释放指定的DllvIreturns>DllImport("kernel32",EntryPoint="FreeLibrary",SetLastError=true)staticexternboolFreeLibrary(IntPtrhModul
21、e);III<summary>IIILoadlibrary返回的函数库模块的句柄III<Isummary>privateIntPtrhModule=IntPtr.Zero;III<summary>IIIGetProcAddress返回的函数指针III<Isummary>privateIntPtrfarProc=lntPtr.Zero;4. 添加LoadDll方法,并为了调用时方便,重载了这个方法:III<summary>III装载DllIII<Isummary>IIIvparamname="lpFileName&
22、quot;>DLL文件名<Iparam>publicvoidLoadDll(stringlpFileName)hModule=LoadLibrary(IpFileName);if(hModule=lntPtr.Zero)throw(newException("没有找到:"+lpFileName+".");若已有已装载Dll的句柄,可以使用LoadDll方法的第二个版本:publicvoidLoadDll(IntPtrHMODULE)if(HMODULE=IntPtr.Zero)throw(newException(”所传入的函数库模块的
23、句柄HMODULE为空.");hModule=HMODULE;5. 添加LoadFun方法,并为了调用时方便,也重载了这个方法,方法的具体代码及注释如下:/<summary>/获得函数指针/</summary>/vparamname="lpProcName">调用函数的名称</param>publicvoidLoadFun(stringlpProcName)/若函数库模块的句柄为空,则抛出异常if(hModule=IntPtr.Zero)throw(newException(”函数库模块的句柄为空,请确保已进行LoadDl
24、l操作!");/取得函数指针farProc=GetProcAddress(hModule,lpProcName);/若函数指针,则抛出异常if(farProc=IntPtr.Zero)throw(newException("没有找到:"+lpProcName+"这个函数的入口点");/<summary>/获得函数指针/</summary>IIIvparamname="lpFileName">包含需调用函数的</param>/vparamname="lpProcName&qu
25、ot;>调用函数的名称publicvoidLoadFun(stringlpFileName,stringIpProcName)/取得函数库模块的句柄hModule=LoadLibrary(lpFileName);/若函数库模块的句柄为空,则抛出异常if(hModule=lntPtr.Zero)throw(newException("没有找到:"+lpFileName+".");/取得函数指针farProc=GetProcAddress(hModule,lpProcName);/若函数指针,则抛出异常if(farProc=IntPtr.Zero)th
26、row(newException("没有找到:"+lpProcName+"点");6. 添加UnLoadDll及Invoke方法,Invoke方法也进行了重载:/<summary>/卸载Dll/</summary>publicvoidUnLoadDll()FreeLibrary(hModule);hModule=IntPtr.Zero;farProc=IntPtr.Zero;Invoke方法的第一个版本:/<summary>/调用所设定的函数DLL文件名</param>这个函数的入口/</summar
27、y>/<paramname="ObjArray_Parameter">实参</param>/<paramname="TypeArray_ParameterType">实参类型</param>/<paramname="ModePassArray_Parameter">实参传送方式</param>/<paramname="Type_Return">返回类型</param>/<returns>返回所调用函数的
28、object</returns>publicobjectInvoke(objectObjArray_Parameter,TypeTypeArray_ParameterType,ModePassModePassArray_Parameter,TypeType_Return)/下面3个if是进行安全检查,若不能通过,则抛出异常if(hModule=IntPtr.Zero)throw(newException("函数库模块的句柄为空,请确保已进行LoadDll操作!");if(farProc=IntPtr.Zero)throw(newException("函
29、数指针为空,请确保已进行LoadFun操作!");if(ObjArray_Parameter.Length!=ModePassArray_Parameter.Length)throw(newException("参数个数及其传递方式的个数不匹配.");/下面是创建MyAssemblyName对象并设置其Name属性AssemblyNameMyAssemblyName=newAssemblyName();MyAssemblyName.Name="InvokeFun"/生成单模块配件AssemblyBuilderMyAssemblyBuilder=
30、AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName,AssemblyBuilderAccess.Run);ModuleBuilderMyModuleBuilder=MyAssemblyBuilder.DefineDynamicModule("InvokeDll");/定义要调用的方法,方法名为“MyFun,”返回类型是“Type_Return参”数类型是“TypeArray_ParameterType”MethodBuilderMyMethodBuilder=MyModuleBuilder.DefineG
31、lobalMethod("MyFun",MethodAttributes.Public|MethodAttributes.Static,Type_Return,TypeArray_ParameterType);/获取一个ILGenerator,用于发送所需的ILILGeneratorIL=MyMethodBuilder.GetILGenerator();inti;for(i=0;i<ObjArray_Parameter.Length;i+)/用循环将参数依次压入堆栈switch(ModePassArray_Parameteri)caseModePass.ByValue
32、:IL.Emit(OpCodes.Ldarg,i);break;caseModePass.ByRef:IL.Emit(OpCodes.Ldarga,i);break;default:throw(newException("第"+(i+1).ToString()+"个参数没有给定正确的传递方式.");if(IntPtr.Size=4)/判断处理器类型IL.Emit(OpCodes.Ldc_I4,farProc.ToInt32();elseif(IntPtr.Size=8)IL.Emit(OpCodes.Ldc_I8,farProc.ToInt64();el
33、sethrownewPlatformNotSupportedException();IL.EmitCalli(OpCodes.Calli,CallingConvention.StdCall,Type_Return,TypeArray_ParameterType);IL.Emit(OpCodes.Ret);/返回值MyModuleBuilder.CreateGlobalFunctions();/取得方法信息MethodinfoMyMethodlnfo=MyModuleBuilder.GetMethod("MyFun");returnMyMethodlnfo.lnvoke(nu
34、ll,ObjArray_Parameter);调用方法,并返回其值Invoke方法的第二个版本,它是调用了第一个版本的:/<summary>/调用所设定的函数/</summary>/vparamname="IntPtr_Function">函数指针</param>/vparamname="ObjArray_Parameter">实参</param>/vparamname="TypeArray_ParameterType">实参类型</param>/vpara
35、mname="ModePassArray_Parameter">实参传送方式</param>/vparamname="Type_Return">返回类型v/param>/vreturns>返回所调用函数的objectv/returns>publicobjectinvoke(lntPtrintPtr_Function,objectObjArray_Parameter,TypeTypeArray_ParameterType,ModePassModePassArray_Parameter,TypeType_Return
36、)/下面2个if是进行安全检查,若不能通过,则抛岀异常if(hModule=IntPtr.Zero)throw(newException(”函数库模块的句柄为空,请确保已进行LoadDll操作!");if(lntPtr_Function=lntPtr.Zero)throw(newException(”函数指针IntPtr_Function为空r');farProc=IntPtr_Function;returnInvoke(ObjArray_Parameter,TypeArray_ParameterType,ModePassArray_Parameter,Type_Return
37、);2)dld类的使用:1.打开项目“Tzb,”向“Forml窗体中添加三个按钮。Name和Text属性分别为“B3、用LoadLibrary方法装载Count.dll,”“B4、调用count方法”,“B5、卸载Count.dll,"并调整到适当的大小及位置。2.在“Form1.cs设计"视图中双击按钮dld类实例:B3,在“B3_Click方'法体上面添加代码,创建一个/<summary>/创建一个dld类对象/</summary>privatedldmyfun=newdld();3.在“B3Click方法体内添加如下代码:加载"
38、;Count.dll"myfun.LoadDll("Count.dll");/myfun.LoadFun("_count4");/调入函数count,"_count4"是它的入口,可通过Depends查看4.“Form1.cs设计"视图中双击按钮B4,在“B4Click方法体内添加如下代码:objectParameters=newobject(int)0;/实参为TypeParameterTypes=newTypetypeof(int);/实参类型为intModePassthemode=newModePassMod
39、ePass.ByValue;/传送方式为值传TypeType_Return=typeof(int);/返回类型为int/弹岀提示框,显示调用myfun.lnvoke方法的结果,即调用count函数MessageBox.Show("这是您装载该Dll后第"+myfun.lnvoke(Parameters,ParameterTypes,themode,Type_Return).ToString()+"次点击此按钮。I!I!挑战杯");5 .“Form1.cs设计”视图中双击按钮B5,在“B5_Click方法体内添加如下代码:myfun.UnLoadDll()
40、;6 按“F5运行该程序,并先点击按钮B3以加载“Count.dll,接着点击按钮B4三次以调用3次“count(O),先后弹岀的提示框如下:这三个提示框所得岀的结果说明了静态变量S经初始化后,再传入实参“0”不会改变其值为“0”7 .点击按钮B5以卸载“Count.dll,再点击按钮B3进行装载“Count.dll,再点击按钮B4查看调用了“count(0)"的结果:从弹岀的提示框所显示的结果可以看到又开始重新计数了,也就是实现了DLL的动态装载与卸载了。(三)调用托管DLL一般方法C#调用托管DLL是很简单的,只要在解决方案资源管理器”中的需要调用DLL的项目下用鼠标右击引用”并
41、选择添加引用”,然后选择已列岀的DLL或通过浏览来选择DLL文件,最后需要用using导入相关的命名空间。(四)动态调用托管DLLC#动态调用托管DLL也需要借助System.Reflectio“.Assembly里的类和方法,主要使用了Assembly丄oadFrom。现在,用例子说明:首先,启动VS.NET,新建一个VisualC#项目使用的模板为类库”,名称为“CsCount,并在类“Classi”中添加静态整型变量S及方法count:/由于static不能修饰方法体内的变量,所以需放在这里,且初始化值为int.MinValuestaticintS=int.MinValue;public
42、intcount(intinit)/判断S是否等于int.MinValue,是的话把init赋值给Sif(S=int.MinValue)S=init;S+;S自增1returnS;/返回S然后,打开项目“Tzb”向“FormT窗体中添加一个按钮,Name属性为“B6”Text属性为用Assembly类来动态调用托管DLL',调整到适当大小和位置,双击按钮B6,转入代码视图,先导入命名空间:usingSystem.Reflection;接着添加Invoke方法和B6_Click方法代码:privateobjectInvoke(stringlpFileName,stringNamespac
43、e,stringClassName,stringlpProcName,objectObjArray_Parameter)Try/载入程序集AssemblyMyAssembly=Assembly.LoadFrom(lpFileName);Typetype=MyAssembly.GetTypes();foreach(Typetintype)查找要调用的命名空间及类if(t.Namespace=Namespace&&t.Name=ClassName)/查找要调用的方法并进行调用MethodInfom=t.GetMethod(lpProcName);if(m!=null)objecto
44、=Activator.CreateInstance(t);returnm.lnvoke(o,ObjArray_Parameter);elseMessageBox.Show("装载岀错!");/trycatch(System.NullReferenceExceptione)MessageBox.Show(e.Message);/catchreturn(object)O;/InvokeB6_Click方'法体内代码如下:II显示count(O)返回的值MessageBox.Show("这是您第"+Invoke("CsCount.dll&qu
45、ot;,"CsCount","Class1","count",newobject(int)0).ToString()+"次点击此按钮。",“挑战杯");最后,把项目“CsCounf'的binDebug文件夹中的CsCount.dll复制到项目“Tzb"的binDebug文件夹中,按“F5运行该程序,并点击按钮B6三次,将会弹岀3个提示框,内容分别是这是您第1次点击此按钮。”、这是您第2次点击此按钮。”、这是您第3次点击此按钮。”,由此知道了静态变量S在这里的作用。(五) C#程序嵌入DL
46、L的调用DLL文件作为资源嵌入在C#程序中,我们只要读取该资源文件并以“byte返回,然后就用“AssemblyLoad(byte);”得到DLL中的程序集,最后就可以像上面的Invoke方法那样对DLL中的方法进行调用。当然不用上面方法也可以,如用接口实现动态调用,但DLL中必须有该接口的定义并且程序中也要有该接口的定义;也可用反射发送实现动态调用4。现在我只对像上面的Invoke方法那样对DLL中的方法进行调用进行讨论,为了以后使用方便及实现代码的复用,我们可以结合上一个编写一个类。1)ldfs类的编写:在项目“Tzb"中新建一个名为ldfs的类,意为“loaddllfromre
47、source”,请注意,在这个类中“resource”不只是嵌入在EXE程序中的资源,它也可以是硬盘上任意一个DLL文件,这是因为ldfs的类中的方法LoadDll有些特别,就是先从程序的内嵌的资源中查找需加载的DLL,如果找不到,就查找硬盘上的。首先导入所需的命名空间:usingSystem.IO;II对文件的读写需要用到此命名空间usingSystem.Reflection;II使用Assembly类需用此命名空间usingSystem.Reflection.Emit;II使用ILGenerator需用此命名空间声明一静态变量MyAssembly:II记录要导入的程序集staticAsse
48、mblyMyAssembly;添加LoadDll方法:privatebyteLoadDll(stringlpFileName)AssemblyNowAssembly=Assembly.GetEntryAssembly();Streamfs=null;try/尝试读取资源中的DLLfs=NowAssembly.GetManifestResourceStream(NowAssembly.GetName().Name+"."+lpFileName);finally/如果资源没有所需的DLL,就查看硬盘上有没有,有的话就读取if(fs=null&&!File.Exi
49、sts(lpFileName)throw(newException("找不到文件:"+lpFileName);elseif(fs=null&&File.Exists(lpFileName)FileStreamFs=newFileStream(lpFileName,FileMode.Open);fs=(Stream)Fs;bytebuffer=newbyte(int)fs.Length;fs.Read(buffer,0,buffer.Length);fs.Close();returnbuffer;/以byte返回读到的DLL添加UnLoadDll方法来卸载DL
50、L:publicvoidUnLoadDll()/使MyAssembly指空MyAssembly=null;添加Invoke方法来进行对DLL中方法的调用,其原理大体上和“Form1.cs"中的方法Invoke相同,不过这里用的是“Assembly丄oad,"而且用了静态变量MyAssembly来保存已加载的DLL,如果已加载的话就不再加载,如果还没加载或者已加载的不同现在要加载的DLL就进行加载,其代码如下所示:publicobjectInvoke(stringlpFileName,stringNamespace,stringClassName,stringlpProcName,objectObjArray_Parameter)try/判断MyAssembly是否为空或MyAssembly的命名空间不等于要调用方法的命名空间,如果条件为真,就用Assembly.Load加载所需DLL作为程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农村义务教育学生营养改善计划实施方案
- 肿瘤化疗护士资质考核试卷附答案
- 电子陶瓷挤制成型工测试验证测试考核试卷含答案
- 网约配送员岗前基础实战考核试卷含答案
- 纸箱纸盒制作工9S考核试卷含答案
- 苯酐装置操作工成果考核试卷含答案
- 老年人能力评估师岗前创新意识考核试卷含答案
- 动物胶提胶浓缩工岗中创新思维考核试卷含答案
- 锯齿剥绒工创新方法水平考核试卷含答案
- 自然保护区巡护监测员岗位晋升强化考核试卷含答案
- 2026年皖豫天一大联考高三10月英语试题(含答案)
- 高标准农田建设项目初步设计技术规程(NYT 5490-2026 )
- T∕CCEAS008-2026 建设工程造价咨询成果文件质量标准
- 第10课《养成遵纪守法好习惯》第1框《增强遵纪守法意识》-【中职思政】《职业道法与法治》课件(高教版2023基础模块)
- 口腔侵入性操作目录
- 2025中远海运集团招聘笔试历年常考点试题专练附带答案详解试卷2套
- 监理全员安全生产责任制内容
- 结构家庭治疗案例介入方法与策略
- 4.1 公民基本义务 课件 人教版八年级道德与法治下册
- 办理酒后驾驶车辆案件程序规定
- T/CCMA 0164-2023工程机械电气线路布局规范
评论
0/150
提交评论