如何在 C# 中访问 class 动态加载的 clr / cli 库

How to access class of dynamically loaded clr / cli library in C#

我是 clr/cli 和 C# 的新手。我的 C# 项目中有一个 clr / cli 库。我想动态加载它并在 C# 中访问其 class 的功能。有人可以提供一些示例或正确的方法吗?

这是我在 Clr / cli 库中声明的 class 头文件

namespace ManagedLibDarkClient {

       public ref class AccountHandler
       {
       public:
              AccountHandler()
              {

              }
              static bool RegisterAccnt(String^ accountID, String^ authCode);
       };
}

请在下面找到我试图访问的 C# class 函数:--

        private void RegisterWindow_ValidateEvent(object sender, ValidateEventArgs e)
        {
                Assembly assembly = Assembly.Loadfile("C:\darkmailWindows\darkmailwindows\Dependencies\ManagedLibDarkMail\Lib\ManagedLibDarkClient.dll");
                if (assembly != null)
                {
                    Type type = assembly.GetType("AccountHandler");
                    var obj = Activator.CreateInstance(type);
                    if (obj != null)
                    {
                        string[] args = { e.AccntInfo.AccntName, e.AccntInfo.AuthCode };
                        type.InvokeMember("RegisterAccnt", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, args);

                    }
                    else
                        MessageBox.Show("Unable to laod object");
                }
                else
                    MessageBox.Show("unable to load assembly");
}
}

在此示例中,我面临 2 个问题:-- 1- LoadFile 挂起并且没有 return 任何东西。 2- 我不知道如何获取我的 clr / cli 函数的 return 值。

这里我还要提一件事。如果我 link 静态地访问它们,我可以访问 clr / cli。但是我必须动态加载它。这对我来说是至关重要的要求。

首先,关于加载问题,请检查工作目录中是否存在 C++/CLI 库的所有本机依赖项 (dll)。
制作包含接口

的第三个程序集
public interface IAccountHandler
{
   bool RegisterAccnt(String accountID, String authCode);
}

从您的项目 C++/CLI 和 C# 添加对此程序集的引用
在 C++/CLI 中:

public ref class AccountHandler : public IAccountHandler
{
   public:
     AccountHandler()
     {

     }

     bool RegisterAccnt(String^ accountID, String^ authCode);
};

然后,在 C# 中:

string filename = "C:\darkmailWindows\darkmailwindows\Dependencies\ManagedLibDarkMail\Lib\ManagedLibDarkClient.dll";

Assembly asm = Assembly.LoadFrom(filename);

foreach (Type t in asm.GetTypes())
{
   if (t.GetInterfaces().Contains(typeof(IAccountHandler)))
   {
      try
      {
         IAccountHandler instance = (IAccountHandler)Activator.CreateInstance(t);

         if (instance != null)
         {
             instance.RegisterAccnt(e.AccntInfo.AccntName, e.AccntInfo.AuthCode);                   
         }
       }
       catch(Exception ex)
       {
          //manage exception
       }
    }
 }

我认为您不需要将 RegisterAccnt 设为静态。

您还可以像从注册的 GAC 或并排程序集中添加对 link 的引用,并手动处理 ResolveAssembly event when it fails loading. See the answer to this question.