如何创建一个可以被动态调用的dll

作者&投稿:睢索 (若有异议请与网页底部的电邮联系)
如何动态调用DLL中类的方法以及属性~

在C#中可以通过Assembly来动态加载DLL,然后由它创建类型,接着通过类型的InvokeMember方法来调用DLL中类的方法以及属性。

为了方便说明一下的方法,先说明一下DLL的代码,大致如下:
using System;
namespace clsTestDll
{
///
/// Summary description for TestDll.
///
public class TestDll
{
private string strName;
public TestDll()
{
//
// TODO: Add constructor logic here
//
strName = "";
}

public string GetValue( int nCount )
{
return string.Format( "Count is {0}!", nCount );
}

public static string GetNewValue( int nCount )
{
return string.Format( "New count is {0}!", nCount );
}

public string Name
{
get{ return strName;}
set{ strName = value;}
}
}
}

大致的步骤如下:
首先加载DLL,具体如下:
// Load assembly from dll file
Assembly assembly = Assembly.LoadFrom( "clsTestDll.dll");

其次,用加载的assembly来定义指定的类型,例如:
// Create new type
Type t = assembly.GetType( "clsTestDll.TestDll");

然后就可以通过新建的类型来调用类的方法。
如果是类的静态方法,可以直接调用,如:
// Call static member function by name
string strReturn = (string) t.InvokeMember("GetNewValue",
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[]{ 12 } );

如果是类的非静态方法或属性,则需要通过类型,先生成类的对象,如:
// Create new object of specific class name
Object obj = t.InvokeMember(
null,
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.CreateInstance,
null,
null,
null );

接着,就可以通过“obj”对象来进行调用了,如:
// Call member function by name
strReturn = (string) t.InvokeMember("GetValue",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.InvokeMethod,
null,
obj,
new object[]{ 12 } );

// Set class property
t.InvokeMember("Name",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty,
null,
obj,
new Object[] {"Test"} );

// Get class property
strReturn = (string) t.InvokeMember("Name",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null,
obj,
null);

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

如何创建一个可以被动态调用的dll
一、DLL中导出类、函数、对象
1. 创建一个空的Win32 Dynamic-Link Library项目Test
2. 在项目中添加一个Test.h头文件,该文件的内容如下://导出类class __declspec(dllexport) CTest
...{
...};//导出函数__declspec(dllexport) void FuncTest();//导出对象extern __declspec(dllexport) CTest ObjTest;这段代码中通过__declspec(dllexport)导出了类CTest、函数FuncTest和对象ObjTest。在.cpp文件中实现上面的声明与类的定义后,经编译就可以生成一个.dll和.lib文件了。
二、静态加载DLL
1. 新建一个Win32 项目。
2. 将上面编译生成的.lib文件复制到,该项目下。
3. 在项目中添加一个Test.h(通过该文件实现对DLL的静态加载),该.h文件的内容主要是从DLL的.h文件中复制过来。具体内容如下:
#pragma comment(lib, "test.lib")//导入类class __declspec(dllimport) CTest
......{
...};//导入函数__declspec(dllimport) void FuncTest();//导入对象extern __declspec(dllimport) CTest ObjTest;这个.h文件与dll的.h的不同就是,在开头加了#pragma comment(lib, "test.lib"),以及类、函数、对象前面的__declspec(dllexport)变成了__declspec(dllimport) 。通过这些修改就可以告诉编译器,这个.h文件中定义的类、声明的函数和对象 都是从test.dll中导入的。在项目中完成对这些类、函数、对象的调用代码后,就可以将其编译成可执行文件。将生成的可执行为文件、以及上面生成的.dll文件复制到同一个文件夹中就可以正常运行这个可执行文件。
三、动态加载DLL
LIBRARY TestImpEXPORTSObjTestFuncTest在完成.def文件后,重新编译dll。重新编译dll后就可以对该Dll进行动态调用了,调用过程的代码如下:
typedef void (*HFUNC)()
HINSTANCE hDLL = LoadLibrary("Test.dll"); //加载DLLif(hDLL)
...{
HFUNC hFun = (HFUNC)GetProcAddress(hDLL, "FuncTest"); //获得Dll中FuncTest函数的指针。
if (hFun)hFun(); //执行函数FuncTestelse
... //没有找到函数FuncTest}else
...{
//加载失败} 上面的代码实现的对DLL中函数的动态调用,在代码中通过LoadLibrary将DLL加载到内存中,然后GetProcAddress获得指定函数所在的内存地址(即该函数的函数指针),获得指向这个函数的指针后就可以对它进行调用了。
对于DLL中对象的动态调用过程基本上是一样的,先将DLL加载到内存,然后通过GetProcAddress获得对象所在的地址。
从上面可以看出,DLL的动态调用过程就是将DLL加载到内存,然后通过GetProcAddress获得DLL中指定对象或函数在该内存中的地址,通过该地址就可以对函数或对象进行调用。由于在C++中没有类的对象,也没有类指针一说,所以是无法动态使用DLL中的类的。

excel中如何动态引用其它工作表
答:1、选中在需要引用数据地方的单元格 2、点击“插入”选项卡项下的“超级链接”3、在超级链接对话框中,选中需要引用数据所在的工作表之后,单击确定即可。

动态链接原理
答:4.建立exports子句,包含供其它应用程序调用的函数和过程名。可以利用标准指示 name 、Index、resident以方便和加速过程/函数的调用;5.输入库初始化代码。这一步是可选的;6.编译程序,生成动态链接库文件。 10.2.1.2 动态链接库中的标准指示 在动态链接库的输出部分,用到了三个标准指示:name、Ind...

请问我有一个.so文件,如何在Linux下编程使用呢?
答:-lxx xx是你的.so文件名 其实使用方法和你使用数学库函数是一样的,源代码中添加 include <math.h>,编译的时候,加上-lm参数。注:linux下的.so文件为共享库,相当于windows下的dll文件。

如何创建和应用一个带有日期域的OneNote动态模板
答: 创建动态模板通过 Gem for OneNote 里的“协作”选项卡 -> “Outlook”组 -> “字段”下拉菜单下。 在表格的第一列插入“日期”字段:<> 在表格的第二列插入“星期名称”字段:<>这样,当使用“字段”下拉菜单下的“用结果替换字段”功能时,将会: <> 会被用今天的日期替换掉...

动态绑定是什么
答:动态绑定是将一个过程调用与相应代码链接起来的行为。是指与给定的过程调用相关联的代码,只有在运行期才可知的一种绑定,他是多态实现的具体形式。‍C++中的实现原理C++中,通过基类的引用或指针调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。用...

...如何在excel表1调用另一个excel表2的数据!动态的,excel表2的数据修改...
答:你把要调用的excel也打开,在要调用格输入公式:=点击被调用的excel文件中的单元格位置。确认后,就可以关闭被调用文件了。以后打开文件时,都会有提示:是不是进行更新。你点击更新就可以了。调用会按被调用格进行更新的。

大学生福音Java常见设计模式总结
答:静态工厂模式是将工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。 2、创建型-抽象工厂模式: 抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象:并且通过隔离具体类的生成,使得客户端不需要明确指定具体生...

MYSQL如何执行动态过程.
答:预制语句的范围是客户端会话。在此会话内,语句被创建。其它客户端看不到它。 在预备了一个语句后,您可使用一个EXECUTE语句(该语句引用了预制语句名称)来执行它。如果预制语句包含任何参数制造符,则您必须提供一个列举了用户变量(其中包含要与参数结合的值)的USING子句。参数值只能有用户变量提供,...

java怎么在静态方法中使用动态方法
答:java在静态方法中使用动态方法的方法是new对象出来,然后用.的方式调用方法:举例如下:定义Outer.java:public class Outer { private static int size;public void dostuff() { size++;System.out.println("hello,I am called");} } 然后在另外的测试类Main中,调用:public class Main { public ...

C++调用dll
答:所以,它定义要在头文件里.现在,可以像先前那样重新编译我们的Test.dll, 我们将得到一个可以被其他VC应用程序所调用的DLL.第四步我们如何调用DLL里的函数呢? 举个例子吧, 我用VS创建一个示例. 选MFC AppWizard (exe),输入项目名字,然后点OK. 选择基于对话框. 然后点Finish. 打开 XXXDlg.cpp(XXX是你的工程...