使用MarshalByRefObject跨应用程序域传递数据 [英] Passing data across appdomains with MarshalByRefObject

查看:502
本文介绍了使用MarshalByRefObject跨应用程序域传递数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在在两个.NET应用程序域之间传递一些数据时遇到了一些麻烦,我希望这里的人可以为我提供帮助.

基本上,我有一个主应用程序( Main ),它将程序集 A B 加载到它的主域中,然后在运行时插件( C ) Main 调用 B 上的create domain方法,该方法创建一个新域并加载 C B 的实例,因此 C 只能访问 B ,而不能访问其他

.

B 包含一个指向 Main 的IDispatch的指针,但只有在使用 C 将其加载到新域中之后,它似乎才能获取它. .我想做的是从 B 的新域实例发送指针的副本,并将其发送到仍在默认域中运行的 A . >

仅出于记录目的,我控制 A,B和C ,但不控制 Main

很抱歉,如果这很难理解,我会尽力解释.

代码:

在A:

public class Tunnel : MarshalByRefObject
{
    public void SetPointer(int dispID)
    {
        IntPtr pointer = new IntPtr(dispID);
    }
}

在B:

//Call by Main after loading plug in but after A.dll is loaded.
public void CreateDomain()
{
  AppDomain maindomain= AppDomain.CurrentDomain;
  tunnel = (Tunnel)maindomain.CreateInstanceAndUnwrap(typeof(Tunnel).FullName,
                                                      typeof(Tunnel).FullName);

   AppDomain domain = base.CreateDomain(friendlyName, securityInfo, appDomainInfo);
   //Load assembly C (plug in) in domain.
   // C uses B so it loads a new instance of B into the domain also at the same time.

  // If I do this here it creates new instance of A but I need to use the one in
  // the main domain.
  //tunnel = (Tunnel)domain.CreateInstanceAndUnwrap(typeof(Tunnel).FullName,
                                                    typeof(Tunnel).FullName);
  tunnel.SetPointer(//Send data from B loaded in new domain.)

}

所以最后看起来像这样:

默认域:

  • Main.dll
  • A.dll
  • B.dll

插入域:

  • B.dll
  • C.dll

解决方案

在上面的代码中,您正在调用

AppDomain.CurrentDomain.CreateInstanceAndUnwrap(...)

这只是在当前域中创建对象的一种简单方法,就像您刚刚调用构造函数一样.您需要在远程域上调用该方法.

AppDomain domain = AppDomain.Create(...)
Tunnel tunnel = (Tunnel)domain.CreateInstanceAndUnwrap(...)

如果您随后调用将在远程对象上运行的tunnel.SetPointer(...).

I'm having a little trouble passing some data between two .NET appdomains and I'm hoping someone on here can help me.

Basically what I have is a main application (Main) which loads assembly A and B into it's main domain, then when I run a plugin(C) Main calls a create domain method on B which creates a new domain and loads C and a instance of B into it, so that C can only access B and not the others.

B contains a pointer to the IDispatch of Main but only it seems to get it after it is loaded into the new domain with C. What I am trying to do is send a copy of the pointer from the new domain instance of B and send it to A which is still running in the default domain.

Just for the record I control A,B and C but not Main

Sorry if this is a bit hard to understand I tried my best to explain it.

Code:

In A:

public class Tunnel : MarshalByRefObject
{
    public void SetPointer(int dispID)
    {
        IntPtr pointer = new IntPtr(dispID);
    }
}

In B:

//Call by Main after loading plug in but after A.dll is loaded.
public void CreateDomain()
{
  AppDomain maindomain= AppDomain.CurrentDomain;
  tunnel = (Tunnel)maindomain.CreateInstanceAndUnwrap(typeof(Tunnel).FullName,
                                                      typeof(Tunnel).FullName);

   AppDomain domain = base.CreateDomain(friendlyName, securityInfo, appDomainInfo);
   //Load assembly C (plug in) in domain.
   // C uses B so it loads a new instance of B into the domain also at the same time.

  // If I do this here it creates new instance of A but I need to use the one in
  // the main domain.
  //tunnel = (Tunnel)domain.CreateInstanceAndUnwrap(typeof(Tunnel).FullName,
                                                    typeof(Tunnel).FullName);
  tunnel.SetPointer(//Send data from B loaded in new domain.)

}

So at the end it looks something like this:

Default Domain:

  • Main.dll
  • A.dll
  • B.dll

Plug in Domain:

  • B.dll
  • C.dll

解决方案

In your code above you are calling

AppDomain.CurrentDomain.CreateInstanceAndUnwrap(...)

This is simply a round-about way of creating an object in the current domain, same as if you just called the constructor. You need to call that method on a remote domain, ie.

AppDomain domain = AppDomain.Create(...)
Tunnel tunnel = (Tunnel)domain.CreateInstanceAndUnwrap(...)

If you then call tunnel.SetPointer(...) that will run on the remote object.

这篇关于使用MarshalByRefObject跨应用程序域传递数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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