|
-
Feb 3rd, 2010, 09:48 AM
#1
Thread Starter
New Member
Runtime discovery of DLLs and their contents
Hi,
I was hoping someone could offer some suggestions to a problem I am having.
I have an application for which I wish to allow plug-ins. The plug-ins would be packaged in DLLs (one or more plug-ins per DLL). The application is written in Visual C++, and I was able (quite easily) to get a sample Visual C++ plug-in DLL to work. The main app looks in a particular folder for plug-in DLLs, and loads all that it finds. The process of loading the DLL calls the DllMain function, which allows the DLL to register all of its plug-ins with the main app. Another way of doing this would be to export a function with a known name in the DLL. That way, the main app can load the DLL, get a pointer to the function, and call that function, which would cause the DLL to register the plug-ins. This gives me the ability to discover the plug-ins at run time; neither the plug-ins nor the DLLs are known at build time.
I have been trying to do something similar with a VB DLL with little success. I was hoping someone would be able to suggest a way to find a VB DLL in a well-known location, load it, and either have it execute a function upon loading, or allow me to discover one or more functions that I can execute. Apparently, there is no way to export a function in a VB DLL the same as I can in a VC++ DLL.
Any help would be greatly appreciated!
JAB
-
Feb 3rd, 2010, 11:11 AM
#2
Re: Runtime discovery of DLLs and their contents
You can use Reflection to do this. The easiest way would be to have an Interface that all .Net class libraries must implement (that way the user can write add-ins in any .Net language).
To do this create a new class library project. Change the default Class1 into an interface instead of a class (by just changing "Class" into "Interface"). Something like this:
Code:
Public Interface IMyPlugIn
Sub PlugInStart()
End Interface
So the idea is that all PlugIns must implement this interface, and the PlugInStart() method would be the starting point of the plug-in (feel free to change the name and add parameters if you like).
Now compile that into an assembly.
In your main app, set a reference to this new assembly. Add code to enumerate the possible plug-ins in the designated folder and pass the file name to a method similar to this one:
Code:
Private Function GetPlugIns(ByVal fileName As String) As List(Of ClassLibrary1.IMyPlugIn)
Dim list As New List(Of ClassLibrary1.IMyPlugIn)
Dim assembly As Assembly = assembly.LoadFrom(fileName)
Dim types() As Type = assembly.GetTypes()
For Each t As Type In types
If t.GetInterface("IMyPlugIn", True) IsNot Nothing Then
list.Add(DirectCast(assembly.CreateInstance(t.FullName), ClassLibrary1.IMyPlugIn))
End If
Next
Return list
End Function
The above returns a List(Of IMyPlugIn), one for each class in the DLL that has implemented that interface.
So to give an example on how to use this, I created a simple Forms app, to which I added a OpenFileDialog and a Button. I also added a reference to the assembly with the above interface. The idea is that when the user click the button you can search for a plug-in dll, using the OpenFileDialog. It would then execute each of the classes within that assembly (each that has implemented the interface that is).
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim plugIns As List(Of ClassLibrary1.IMyPlugIn) = GetPlugIns(OpenFileDialog1.FileName)
If Not plugIns.Count = 0 Then
For Each plugin As ClassLibrary1.IMyPlugIn In plugIns
plugin.PlugInStart()
Next
End If
End If
End Sub
I would have written much of this code using LINQ, but you hadn't mentioned which version of VB you where using.
-
Feb 3rd, 2010, 11:26 AM
#3
Thread Starter
New Member
Re: Runtime discovery of DLLs and their contents
Wow! Thanks for the reply! That was like a tutorial in reflection!
What you suggest seems like a good solution, and may be the best. Unfortunately, the main app is VC++ (pre .NET. Converting it to .NET is out of the question at this point). I had to extend this app several months ago to create a remoting interface (via .NET), and for that, I had to create a bridge (managed/unmanaged) DLL. I could do the same here, I suppose.
The lazy guy in me was hoping for a simpler method. Not that what you suggest is not simple, but marrying it to my existing app will be a pain.
-
Feb 3rd, 2010, 11:30 AM
#4
Re: Runtime discovery of DLLs and their contents
Well, VB.Net only creates managed code, including its DLL's. You could write a .Net PlugIn launcher in VB if you also create some form of communication between the launcher and your C++ app, for example using named pipes.
-
Feb 12th, 2010, 02:11 PM
#5
Thread Starter
New Member
Re: Runtime discovery of DLLs and their contents
As a followup, I was able to use Joacim Andersson's suggestion. I created a mixed (managed/unmanaged) DLL (in C++) that defines an IPlugin interface. This DLL is loaded by my C++ app. The app calls a function on the mixed DLL that loads any plug-in DLLs and catalogs them.
My test VB .NET project references the mixed DLL and contains a class that implements the IPlugin interface.
This all works well and my VB .NET plug-ins are showing up in my legacy, unmanaged C++ app!
Thanks for the help!
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|