0

I am novice in clr / cli and C#. I have one clr / cli library in my C# project. I want to load it dynamically and access the function of its class in C# . Can some one provide some example or right way to doing it.

Here is My header file of class declaration in Clr / cli library

namespace ManagedLibDarkClient {

       public ref class AccountHandler
       {
       public:
              AccountHandler()
              {

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

Please find below the function of my C# class on which I have tried to access it:--

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

Here in this example I am facing 2 issue :-- 1- LoadFile hangs and did not return any thing. 2- I dont know how to get return value of my clr / cli function.

Here I would like to mention one more thing. I can access clr / cli if I link them statically. But I have to load it dynamically. It is crucial requirement for me.

Ðаn
  • 10,934
  • 11
  • 59
  • 95
  • It kinda sounds like there might be a deadlock. If you put a break point in your DllMain, does it get hit? if you step through, does DllMain complete? If you let it run until it hangs and then pause execution, is any of your (native) code on the stack (of any thread in that process)? – Brian Reichle May 24 '17 at 21:54

2 Answers2

1

First af all, regarding the loading issue, check that all the native dependencies (dlls) of your C++/CLI library are present in the working directory.
Make a third assembly containing an interface

public interface IAccountHandler
{
   bool RegisterAccnt(String accountID, String authCode);
}

Add a reference to this assembly from both your projects, C++/CLI and C#
In C++/CLI:

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

     }

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

Then, in 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
       }
    }
 }

I think you don't need to make RegisterAccnt static.

Simone Cifani
  • 784
  • 4
  • 14
  • HI Simon, thanks for quick reply and good example. But I think my issue is that I am not able to load managed dll (clr / cli) using loadfile as it hangs there. It will not work in this case as well. Do you think it is because in my clr / cli dll, I have used both unmanaged and managed code and loadfile works only for pure managed code ? can we use PInvoke to access class /function of clr /cli dll. – user1677408 May 24 '17 at 09:50
  • What error do you get? Do you get same error even using Assembly.LoadFrom(...)? Just to investigate, have you tried to add your library as a static reference? PInvoke is actually used to access native libraries, you have C++/CLI, which can be considered a .Net assembly – Simone Cifani May 24 '17 at 10:29
  • Hi Simone, yes.. it works with static library. Problem is it just hangs there for long time instead of throwing an exception which was much easy to analyze. – user1677408 May 24 '17 at 10:45
  • HI SImone, I have created a wrapper C# library. I have referenced clr/cli library as static in my wrapper lib and call the function of managedLibDarkClient from inside. Now in my main C# lib, I have tried to dynamically load wrapper lib and it gives error that unable to load ManagedLibDarkClient lib or their dependencies. Now my question is how the system is loading it statically but not able to load it dynamically ? – user1677408 May 24 '17 at 11:18
  • It is a very strange behaviour. You may use a tool called [Fusion](https://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.71).aspx), which is part of the .Net framework, to log errors on loading. Maybe this will give you more information about the issue. Sometimes loading fails because the C++/CLI assembly depends on a native dll. In this case you are able to reference it but the loading fails. – Simone Cifani May 24 '17 at 12:06
  • Hi Simon, thanks for your help. I have found the issue. It emerges as environment issue on my machine. Same code is working on every other machine. I have reinstalled some visual studio packages and it is working fine. – user1677408 May 29 '17 at 17:51
0

You also can add the reference like you would do to link from a GAC registered or side by side assembly and manually handling the ResolveAssembly event when it fails loading. See the answer to this question.