相当于.NET中的运行时动态链接 [英] Equivalent to run-time dynamic linking in .NET

查看:47
本文介绍了相当于.NET中的运行时动态链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非托管的Win32应用程序,它从外部位置查找DLL的名称(

编译时未知),使用LoadLibrary加载它,然后

在三个导出函数上使用GetProcAddress(其名称和签名

在编译时是已知的)。然后应用程序在执行过程中根据需要调用这些函数

。根据具体情况,可能会有零,一,

或许多单独的DLL加载,这些都符合这种模式(也就是说,他们

都导出相同的三个函数) 。


我需要将此应用程序转换为托管代码。它需要执行相同的

行为:从外部

位置查找DLL程序集(在编译时未知),以某种方式加载它并调用它的导出按钮。功能(大概在

..NET这些将是公共类的公共方法)。


在我深入研究构成System :: ::反思,

这样我可以直接从DLL中拖出类型和方法

自己,我有3个问题:


1.使用System :: Reflection是运行时动态

链接的首选方式在.NET?

2.如果没有,处理这种情况的首选方法是什么?

3.有没有人知道任何设计模式或至少是详细记录

这类工作的例子?


Sean

解决方案

< blockquote>Sean M. DonCarlos < SE ******** @ newsgroups.nospam>在留言中写道

新闻:1C ********************************** @ microsof t.com ...

我有一个非托管的Win32应用程序,它从外部位置查找DLL的名称(在编译时未知),使用LoadLibrary加载它,以及
然后
在三个导出函数上使用GetProcAddress(其名称和
签名在编译时是已知的)。然后,应用程序会在执行过程中根据需要调用这些函数。根据具体情况,可能有零,一个,
或许多单独的DLL加载,所有这些都符合这种模式(即,它们都导出相同的三个函数) 。

我需要将此应用程序转换为托管代码。它需要执行相同的行为:从
外部位置查找DLL程序集(在编译时未知),以某种方式加载它并调用它的导出部分。功能(大概在.NET中,这些将是公共类的公共方法)。

在我深入研究构成System :: Reflection的精彩混乱之前,
以便我可以把这些类型和方法直接从
DLL中拖出来,我有3个问题:

1.使用System :: Reflection是做的首选方式吗?运行时
动态链接在.NET?


我不喜欢使用像首选方式这样的术语。这就是我这样做的方式。

2.如果没有,处理这类情况的首选方法是什么?


FWIW:这是我的选择。

有没有人知道任何设计模式或至少有一个记录良好的
示例工作类型?




在我的应用程序中,我做了几乎你建议支持的内容.Net

" plugins"。


在我的例子中,有一个基类具有所需的方法。我需要

,插件可以从我的基类派生出来。我使用

Reflection :: Assembly :: LoadFrom()这样我就可以从查找到的地方加载程序集

。程序集的GetTypes()方法在程序集中返回一个数组

类型。它使用Type类的BaseType成员确保

我有我需要的那类帽子。我使用了Type类的GetMethod()成员来获取与GetProcAddress()类似的函数。最后

MethodInfo类的Invoke成员获得了我需要的动态调用




问候,


Sean M. DonCarlos写道:

1.使用System :: Reflection是首选方式做运行时动态链接在.NET中?




这是一个从应用程序加载插件的示例(使用

C ++ / CLI,假设你' '使用VC ++ 2005):


#using" Interface.dll"

使用命名空间系统;


反射::汇编^汇编=

反射::汇编:: LoadFrom(" Plugin1.dll");

类型^ t = assembly-> GetType( " Plugin.Plugin1");

Plugin :: Interface ^ plugin =

safe_cast< Plugin :: Interface ^>(Activator :: CreateIns tance(t)) ;

String ^ result = plugin-> GetName();

接口是从interface.dll程序集发布的,声明为


命名空间插件

{

公共接口类接口

{

public:

虚拟字符串^ GetName()抽象;

};

}

插件在Plugin1.dll中实现如下:


#using" Interfa ce.dll"


命名空间插件

{

公共引用类插件1:公共接口

{

public:

virtual String ^ GetName(){return" Hello" ;; }

};

}

关键是确保每个插件DLL使用与
$ b $相同的接口b申请。在.NET中,仅以相同的方式命名两个类并不是
确保这两个类完全相同。此插件示例

仅在Interface与应用程序

和插件中的完全相同的类时才有效。确保这一点的最常用方法是引用

相同的接口(例如,使用#using指令),而不是

#包括接口的声明。如果您使用#include

而不是#using,那么两个接口类将完全独立,并且应用程序无法加载插件。


在这个例子中,我选择引入一个单独的interface.dll,它是由应用程序和插件引用的
。我相信你可以从应用程序本身发布Interface类,并从插件中引用它来获取
,但我还没有尝试过。我不确定#using是否允许.exe允许使用#。或者用于.dll或.dll。只有。


Tom


" William DePalo [MVP VC ++]"写道:

我讨厌使用像首选方式这样的术语。这是我的方式。


我自己并不关心这个词,但是我还没有想出一个更好的

术语。整句话。我只是想确保在

之前我投入时间和精力学习反思,反思是最好的处理问题的方法,如果不是 ;最好的"方式。

2.如果没有,处理这种情况的首选方法是什么?



FWIW:这是我的选择。

有没有人知道任何设计模式,或者至少有一个记录良好的
这类工作的例子?


在我的应用程序中,我做了几乎你建议支持.Net
插件。

在我的情况下,有一个基类具有所需的方法。我要求
插件来自我的基类。我使用了
Reflection :: Assembly :: LoadFrom(),这样我就可以从查找到的地方加载程序集。程序集的GetTypes()方法返回程序集中类型的数组。它使用Type类的BaseType成员来确保我有我需要的那类帽子。我使用了Type类的GetMethod()成员来执行与GetProcAddress()类似的功能。最后,MethodInfo类的Invoke成员获取了我需要的动态调用。




如果只有这个段落在Visual中工作室文档,它会节省很多时间
!谢谢!


Sean


I have an unmanaged Win32 app that looks up the name of a DLL (unknown at
compile time) from an external location, loads it with LoadLibrary, and then
uses GetProcAddress on three exported functions (whose names and signatures
are known at compile time). The app then calls these functions as needed
throughout its execution. Depending on circumstances, there may be zero, one,
or many separate DLLs loaded that all conform to this pattern (that is, they
all export the same three functions).

I need to convert this app to managed code. It needs to perform the same
behavior: look up a DLL assembly (unknown at compile time) from an external
location, load it somehow and call its "exported" functions (presumably in
..NET these would be public methods of a public class).

Before I dive into the wonderful mess that constitutes System::Reflection,
so that I can supposedly drag the types and methods straight out of the DLLs
themselves, I have 3 questions:

1. Is using System::Reflection the preferred way of doing "run-time dynamic
linking" in .NET?
2. If not, what is the preferred way of handling this type of situation?
3. Does anyone know of any design pattern or at least a well-documented
example for this type of work?

Sean

解决方案

"Sean M. DonCarlos" <se********@newsgroups.nospam> wrote in message
news:1C**********************************@microsof t.com...

I have an unmanaged Win32 app that looks up the name of a DLL (unknown at
compile time) from an external location, loads it with LoadLibrary, and
then
uses GetProcAddress on three exported functions (whose names and
signatures
are known at compile time). The app then calls these functions as needed
throughout its execution. Depending on circumstances, there may be zero,
one,
or many separate DLLs loaded that all conform to this pattern (that is,
they
all export the same three functions).

I need to convert this app to managed code. It needs to perform the same
behavior: look up a DLL assembly (unknown at compile time) from an
external
location, load it somehow and call its "exported" functions (presumably in
.NET these would be public methods of a public class).

Before I dive into the wonderful mess that constitutes System::Reflection,
so that I can supposedly drag the types and methods straight out of the
DLLs
themselves, I have 3 questions:

1. Is using System::Reflection the preferred way of doing "run-time
dynamic
linking" in .NET?
I hate to use terms like "preferred way". It is the way I do it.
2. If not, what is the preferred way of handling this type of situation?
FWIW: it''s my choice.
Does anyone know of any design pattern or at least a well-documented
example for this type of work?



In an application of mine I do pretty much what you suggest to support .Net
"plugins".

In my case there is a base class that has the required method(s). I require
that the plugins be derived fom my base class. I use
Reflection::Assembly::LoadFrom() so that I can load the assembly from where
ever the lookup takes me. The assembly''s GetTypes() method returns an array
of types in the assembly. It use the Type class''s BaseType member to insure
that I have the kind of class hat I need. I used the GetMethod() member of
the Type class to perform a similar function to GetProcAddress(). Finally
the Invoke member of the MethodInfo class gets me the dynamic invocation
that I need.

Regards,
Will


Sean M. DonCarlos wrote:

1. Is using System::Reflection the preferred way of doing "run-time dynamic
linking" in .NET?



Here''s an example of loading a plugin from an application (using
C++/CLI, assuming you''re using VC++ 2005):

#using "Interface.dll"
using namespace System;

Reflection::Assembly^ assembly =
Reflection::Assembly::LoadFrom("Plugin1.dll");
Type^ t = assembly->GetType("Plugin.Plugin1");
Plugin::Interface^ plugin =
safe_cast<Plugin::Interface^>(Activator::CreateIns tance(t));
String^ result = plugin->GetName();
The interface is published from the interface.dll assembly, declared as

namespace Plugin
{
public interface class Interface
{
public:
virtual String^ GetName() abstract;
};
}
And the plugin is implemented like this in Plugin1.dll:

#using "Interface.dll"

namespace Plugin
{
public ref class Plugin1 : public Interface
{
public:
virtual String^ GetName() { return "Hello"; }
};
}
The key is to ensure that each plugin DLL uses the same Interface as the
application. In .NET, just naming two classes the same way alone doesn''t
ensure that the two classes are the exact same type. This plugin sample
only works if Interface is the exact same class in both the application
and the plugin. The most common way to ensure this is by referencing the
same Interface (for example, with the #using directive), instead of
#including the declaration for Interface. If you were to use #include
instead of #using, the two Interface classes would be completely
independent, and the application would fail to load the plugin.

In this example I chose to introduce a separate interface.dll, which is
referenced by both the application and the plugin. I believe you could
publish the Interface class from the application itself and reference it
from the plugin, but I haven''t tried that. I''m not sure if #using is
allowed for an ".exe" or for a ".dll" only.

Tom


"William DePalo [MVP VC++]" wrote:

I hate to use terms like "preferred way". It is the way I do it.
I don''t much care for the term myself, but I''ve yet to come up with a better
term that isn''t a whole sentence. I was just trying to make sure that before
I invested time and effort learning about reflection that reflection was at
least a valid way of handling the problem, if not the "best" way.

2. If not, what is the preferred way of handling this type of situation?



FWIW: it''s my choice.

Does anyone know of any design pattern or at least a well-documented
example for this type of work?



In an application of mine I do pretty much what you suggest to support .Net
"plugins".

In my case there is a base class that has the required method(s). I require
that the plugins be derived fom my base class. I use
Reflection::Assembly::LoadFrom() so that I can load the assembly from where
ever the lookup takes me. The assembly''s GetTypes() method returns an array
of types in the assembly. It use the Type class''s BaseType member to insure
that I have the kind of class hat I need. I used the GetMethod() member of
the Type class to perform a similar function to GetProcAddress(). Finally
the Invoke member of the MethodInfo class gets me the dynamic invocation
that I need.



If only this paragraph had been in the Visual Studio documentation, it would
have saved a lot of time! Thanks!

Sean


这篇关于相当于.NET中的运行时动态链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆