微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 c++/cli dll 加载到 c# appdomains 的标准/正确方法是什么?

如何解决将 c++/cli dll 加载到 c# appdomains 的标准/正确方法是什么?

我需要创建一个 C# 应用程序,我可以在其中动态加载和卸载 C++/CLI dll,所以我使用的是 appdomains。

我正在以这种方式加载 dll(在我的应用程序域中):

Assembly assembly = AppDomain.CurrentDomain.Load("dllName");
Type m_configType = assembly.GetType("typeName");
object m_configObject = Activator.CreateInstance(m_configType);

我可以加载 dll 并根据需要使用它,但问题是当代码运行我复制的最后一行代码时,dll 会加载到我的所有应用程序域中。

我该如何防止这种行为?

输出

Output

我会给你重新创建行为的项目代码

AppdomainTest 项目 - Program.cs

static void Main(string[] args)
{
  AppDomain appDomain = CreateAppDomain("PluginLoaderDomain");
  PlugIn plugin = InstantiatePlugin("PluginLoader",appDomain);
  Console.WriteLine("Main domain assemblies before loading:");
  PrintLoadedAssemblies();
  plugin.LoadRuntimeAssembly();
  Console.WriteLine("Created appdomain assemblies:");
  plugin.PrintLoadedAssemblies();
  Console.WriteLine("Main domain assemblies after loading:");
  
  PrintLoadedAssemblies();
  Console.WriteLine("Unloading appdomain");
  Console.WriteLine("");
  Console.WriteLine("Main domain assemblies after unloading:");
  AppDomain.Unload(appDomain);
  PrintLoadedAssemblies();
  IsUnloaded(plugin);
}
static AppDomain CreateAppDomain(string dllName)
{
   AppDomainSetup setup = new AppDomainSetup()
   {
      ApplicationName = dllName,ConfigurationFile = dllName + ".dll.config",ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,ShadowcopyDirectories = "true",ShadowcopyFiles = "true"
   };
   AppDomain appDomain = AppDomain.CreateDomain(setup.ApplicationName,AppDomain.CurrentDomain.Evidence,setup);

   return appDomain;
}
static PlugIn InstantiatePlugin(string dllName,AppDomain domain)
{
   PlugIn plugIn = domain.CreateInstanceAndUnwrap(dllName,dllName + ".PlugIn") as PlugIn;

   return plugIn;
}
static void IsUnloaded(PlugIn plugin)
{
   bool unloaded = false;

   try
   {
      Console.WriteLine(plugin.Name);
   }
   catch (AppDomainUnloadedException)
   {
      unloaded = true;
   }
   catch (Exception ex)
   {
      Console.WriteLine(ex.Message);
   }

   if (unloaded)
   {
      Console.WriteLine("Appdomain unloaded.");
   }
   else
   {
      Console.WriteLine("Error! Appdomain not unloaded.");
   }
}

PluginLoader 项目 - Plugin.cs

public class PlugIn : MarshalByRefObject
{
   private string name;

   public string Name { get { return name; } }

   public void Initialize()
   {
      name = "PlugIn 1";
   }

   public void LoadRuntimeAssembly()
   {
      Assembly assembly = AppDomain.CurrentDomain.Load("dllName");
      Type m_configType = assembly.GetType("typeName");

      object m_configObject = Activator.CreateInstance(m_configType);
   }
}
public void PrintLoadedAssemblies()
{
   Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
   Console.WriteLine("----------------------------------");

   foreach (Assembly assembly in assemblies)
   {
      Console.WriteLine(assembly.FullName.Substring(0,assembly.FullName.IndexOf(',')));
   }

   Console.WriteLine("----------------------------------");
   Console.WriteLine("");
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。