How to handle dynamically loaded managed libraries in c# - c#

I wrote an application in C# and added a kind of API for it.
With this API you can write plugins as dll´s which underlie some interface rules.
I want to make it possible to open the dll file via OpenFileDialog and use its content.
My API is a managed library, so I just add a reference, but I want to use the dll without knowing the name of the dll file. Also the namespace is another each library.
How do I load a dll and run the code within it?

What you are describing is commonly termed a Plugin System. Googling for something like "Create Plugin system using C#" will probably give you lots of information such as the below:
http://www.codeproject.com/Articles/4691/Plugin-Architecture-using-C
The basic idea is:
Define an interface that your program implements to allow a plugin to get information from your program.
Define an interface that all plugins will implement, to allow your program to call the plugin's methods that will do something.
Put those interfaces in a separate dll that's referenced by your program and by any plugin dlls.
Provide some way of finding dlls with types implementing your plugin interface, e.g. your OpenFileDialog.
Load the dll and find types that implement your plugin interface (using reflection).
Instanciate those types using reflection.
Call the methods on those types via the interface, as appropriate.
Regarding managed/non-managed. A managed DLL is one that is built/coded using the .net managed runtime. This would be things coded in a .net language such as c#.
A non-managed dll is more or less anything coded in a different language.
What you referred to as a non-managed dll I would refer to as a dynamically loaded managed dll. I.e. it's still a managed dll (coded in a .net language), but isn't loaded until the program is already running.

You can load a managed assembly from a dll file with Assembly.LoadFrom Method (String) (See also Best Practices for Assembly Loading).

Related

How do I know that a method in a DLL calls a method of another DLL?

For example:
There is API a.1 in DLL A and API B.1 in DLL B.
API A.1 calls API B.1.
Is there an open source tool or method to know this call path(A.1->B.1)?
.Net assemblies contain a list of referenced assemblies. This can be inspected by tools like IL SPy.
There is no easy way to check if a specific method on one assembly may calls another assembly. You could perhaps inspect the CIL code for this, but it will require a bit more work.
There is also native dependencies, these are not listed in the same way, and use another method to load.

Using the same dll in another dll and a third codebase that runs the executable

So basically I am creating my own dll for use in a c# codebase, using c++ and a c-style layer for exporting functions. The issue is that both the c# part of the code (which actually runs and uses the dll) and my library itself both use another library (it's imgui, so lets call it such, even though it is irrelevant mostly) that runs on global state.
I initialize imgui to certain settings in my own dll and then use some of its functions in the c# code. Currently I am simply compiling the library into my dll and doing a c# binding myself that issues calls to imgui through my own dll. My question is whether I can use imgui as a dll for use both in my own dll and the main c# program in such a way that state is shared and the initialization step initializes the same code for both my own dll and the c# code.
That is, the c# code calls one of my functions in my own dll to initialize it, that function imports a dll (imgui), in the common directory for both my dll and the executable, and initializes IT. After this, the main c# program that imports both my dll and imgui then calls imgui functions to manipulate it's state. Will my dll and the main c# program be manipulating the same imgui state?
Generally yes
I say 'generally' because there are some conditions:
Everything needs to be in the same process (you are not clear on this but I assume so)
Both callers need to be able to get some handle on the state. So for example, if the state is memory allocated on the heap, then both callers need to be able to get a pointer to it, or else it needs to be a global variable somewhere they can access, either directly or indirectly.
Really it is the same as if it was 3 different C# modules
(also adding the disclaimer to think if you really need to use the C++, but I'm sure you have your reasons)

In C# While Using Interop HTML 2 XHTML Lib Dll Source Code Giving Error

When I try to Convert HTML to XHTML Tag I'm getting the following error...
Error: Retrieving the COM class factory for component with CLSID
{59939390-0E6A-4F1B-A742-20C5459501F7} failed due to the following
error: 80040154.
After googling I found few solutions:
Registering the DLL into regsvr32 "E:Source
Code\bin\Interop.HTML2XHTMLLib.dll"
I'm just tried to register the dll. But E:Source Code\bin\Interop.HTML2XHTMLLib.dll was loaded. But the DllRegisterServer entry point was not found this error message was displayed. Why..?
Recompiled my project for x86 and x64.. no use..
VB.NET Code:
Dim xhtmlUtil As New XHTMLUtilities // Here itself im getting the above error.
sFormattedOutput = xhtmlUtil.convertToXHTML(sInputline) //Send it for conversion
My Operating system is Windows XP 32-bit Service pack 3. My application was done in VS2008. currently I'm working with VS2010.
Here what I'm missing. Could any one help me to figure out this problem?
Thanks in advance.
i'm just tried to register the dll. But E:Source Code\bin\Interop.HTML2XHTMLLib.dll was loaded. But the DllRegisterServer entry point was not found this error message was displayed. why?
The Interop.HTML2XHTMLLib.dll file isn't the library you want to register using regsvr32. It is only the managed interop assembly, generated make COM objects accessable for your .NET application. You actually need to register the type library for the HTML2XHTMLLib.dll.
To do this, you have two options:
Find the redistributeable package, that contains the library and install it together with your application.
On your development system, open the "Add references" dialog of Visual Studio. Choose the COM tab and search for the library (just like you did when you've added the reference). There you will find the absolute path to the library. Copy the library to the client system and register it using regsvr32.
Since I do not know the source of the HTML2XHTMLLib, I can only suggest those ways. You should prefer the first one.
Since you've started a bounty on this, I want to go a little bit more into detail on COM and the InterOp.
Differences between COM and .NET assemblies
There are two types of servers in COM: InProc-servers and OutProc-servers. InProc (In Process) are servers we usually know als DLL. OutProc (Out of Process) servers are standing alone, running in their own process. We know them as EXEcutables.
You want to consume an InProc-server. Your COM-server (HTML2XHTMLLib) consists out of two parts:
A type library (.tlb), that contains meta-information about the server, it's contained objects and their accessability.
A library, containing the code where all the objects are implemented. The library also exports the following static functions:
DllGetClassObject – Tries to create an instance of an object, defined inside the server
DllCanUnloadNow – Tells the COM environment, whether or not the server can be released, because it isn't used by any other process any more.
DllRegisterServer – Called by regsvr32 to register the previously mentioned type library in the Windows Registry, to make it visible to clients and the COM environment.
DllUnregisterServer – Does the exact opposite, when called through regsvr32 -u.
The type library can also a resource of the DLL or EXE file, so that there's only one file. For C# developers this seems somehow confusing, since meta-information is directly compiled into a.NET assembly and accessable through reflection.
The InterOp: A wrapper between .NET and COM
So basicly type libraries describe everything that is needed by the .NET reflection to access the objects exposed through COM. But the problem is, that COM-components are stored in a different format:
Usually they are directly compiled into machine code: You cannot link a .NET assembly, compiled with AnyCPU against a COM-server. COM-servers are directly compiled to either x86-assembler, or x86-64-assembler. They have fixed pointer sizes and thus are only compatible with one of the compilation-models.
COM defines rules for memory management. Each COM-object must implement the IUnknown-interface. This interface defines three methods. The methods AddRef and Release are for memory management purposes. Whenever a client accesses an COM object it needs to call AddRef. This increases a counter by one. When the client does not need the object anymore, it calls Release instead of deleting the object, resulting in a counter decrement. If the pointer reaches 0, the object delete's itself. This is different from how .NET manages memory. In .NET the garbage collector visits each object on the heap in a non-deterministic manner (you cannot determinate the exact point of time an object get's deleted) and releases the object, when there are no references left to it.
COM defines rules for identity. Whenever you only want to access an base interface of an object, you have to call the QueryInterface method, defined by IUnknown. This method is guaranteed to allways return the same pointer, when a specific interface get's queried. This might be also true for .NET (besides you are overloading some operators), but the way .NET ensures object identity is different.
COM defines rules for object relations. Crazy stuff like Aggregation and Containment, which do also exist in .NET, but are implemented differently.
COM defines different multithreading rules, like Single Threaded Appartments and Multi Threaded Appartments. Those threading models define how objects interact, when they are coexisting in different manners. In .NET you have to perform each synchronisation process manually.
This list may not be complete, neither I want to go into detail any further, because it is only incidental for your question, but you see, that there are some big differences between .NET and COM. And to manage those differences there is a layer between both worlds: the COM InterOp.
If you are calling a COM server from .NET, the InterOp is nothing more than a .NET assembly, that does all the hard work under the hood. It get's created using the tlbimp.exe tool. Visual Studio typically calls it for you whenever you are referencing a library from the COM tab. The result is the library you wanted to register: InterOp.Libary.dll. This library redefines all types of the type library of the COM server, implements the rules required by COM and performs the actual calls for you. However it is a managed .NET library which does not define the methods, described earlier. This is why regsvr32 cannot find the DllRegisterServer entry point.
The way described above is only a one-way with an unmanaged COM server and a managed .NET client. There is also the other way, with the counterparts tlbexp.exe and regasm.

How to export c# dll functions to be able to access them from another application

I would like to know how can I export dll functions because I have a program which requires function exporting in order to use them.
Can I accomplish this in c#?
PS: The program who's using the dll is not O.Source and I can't add the reference into it.
1 You can use MEF Framework - Based on Export, Import and Catalog
Link : http://msdn.microsoft.com/en-us/library/dd460648.aspx.
2 You can also expose on your network by using WCF
Link : http://msdn.microsoft.com/en-us/library/ms735119(v=vs.90).aspx
Nota : You have another possibilities, it depends on your choice and technical constraints
If the other application is a .NET application, it can add a reference to your assembly (DLL), and use any public type defined within the assembly. This gives it full access to your code.
If you need a native API for use with your C# code, then this becomes more difficult. There are a few options:
Use COM. You can mark types as ComVisible, and register the assembly. This allows your code to be accessed via COM.
Use C++/CLI to build a native wrapper around your managed types. This would require a separate assembly (DLL) that provides the native exports, and uses the managed types internally.
The best option here really depends on how the "other application" needs to gain access to your code. If it's not a .NET application, COM is typically the simplest (and often nicest) option.
Probably, the closest option to your requirement would be using Unmanaged Exports.
For other options, see here and here.

.NET Client supporting multiple versions of an unmanaged DLL

I am developing a .NET 4.0 client that will utilize a C Library for data processing. The user will be able to specify the DLL file they wish to load for processing.
I am doing late binding / assembly loading as described here. http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_.aspx
For each DLL, the same method call sequences will be the same in my client, but the method signatures will change or the data structs passed in will change. The data populated with the structures will be different depending on the version of the DLL and other factors. Example, the definition of MyStruct will change depending on the version of the DLL.
public delegate int INTF_my_method(ref MyStruct pDataStruct);
What design patterns or design decision are recommended for this approach? I need to load the appropriate C method delegates and data definitions based on the version of the DLL that the user has specified, and populate the structures appropriately. Has anyone done something like this before?
There is no clean approach to this, neither in managed code nor native code. The best you could possibly do is to declare an interface type that tries to cover all possible versions and then write concrete wrapper classes for each individual version of the API. If there's at least some common functionality then you can shovel that in a base class.
Notable too is that you cannot just let the user pick a DLL, you have to pair the DLL with the concrete wrapper class instance.
Building this kind of flexibility in your program is obviously very expensive.
You can load different versions of your DLLs, but only from separate AppDomains. That is, for each DLL you want to load, you will have to create a new AppDomain.

Categories

Resources