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

时间:2017-05-24 08:18:32

标签: c# .net clr managed-c++

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

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

namespace ManagedLibDarkClient {

       public ref class AccountHandler
       {
       public:
              AccountHandler()
              {

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

请在下面找到我尝试访问它的C#类的功能: -

        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");
}
}

在这个例子中我面临两个问题: - 1- LoadFile挂起并且没有返回任何内容。 2-我不知道如何获得我的clr / cli函数的返回值。

我想在此提及另一件事。如果我静态链接它,我可以访问clr / cli。但我必须动态加载它。这对我来说是至关重要的。

2 个答案:

答案 0 :(得分:1)

首先,关于加载问题,检查工作目录中是否存在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静态。

答案 1 :(得分:0)

您还可以添加引用,就像从GAC注册或并排的程序集进行链接一样,并在加载失败时手动处理ResolveAssembly事件。请参阅this question的答案。