• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 736
  • Last Modified:

late binding to an unmanaged dll

Hello all,
      I am writing an application in C# that has a need to call DLLs whose file name, path, entry point and parameter signature will be passed into my application at run time.  I have found a few vague references to using Reflection.Emit, but after reading the articles, it seems that Reflection.Emit can not handle the criteria outlined above.  All the documentation I have read about P/Invoke requires early binding to a known file, entry point and parameter signature.  I have read one article that talks about writing an assembly language DLL as a bridge between .NET and unmanaged DLLs.  While an extraneous DLL is an option, I would prefer to find a more elegant solution to the problem.  The one criterion above that is flexible is the parameter signature, but again I would prefer to be able to allow flexibility in that as well.

So to sum up, the problem is allowing .NET to call an unamanged DLL whose details (file name, entry point and parameter signature) are not known at compile time.

Thanks all.
0
edc
Asked:
edc
  • 2
1 Solution
 
vascovCommented:
Just write some C# that uses PInvoke (or your prefered .NET language) out to a .cs file, compile it, and load it using Reflection.

That said, doing PInvoke knowing the signatures and sometimes implementation details can be hard, not knowing can be REALLY hard. Note that even doing that in unmanaged code is still hard. DLL entrypoints have little to no information about param types and characteristics, so you'll have to trust your user's input, as well as all the "tips" on how to treat each param (that's what the PInvoke attributes are for)

Another option is to build a Managed CPP assembly that deals with calling the unmanaged call and does all the marshaling, etc... (essentially redoing what PInvoke does).

Vasco
0
 
edcAuthor Commented:
Hi Vasco,

>>not knowing can be REALLY hard (Tell me about it :) )

The project is a workflow engine.  Entities in the workflow have to be able to call out to user specified DLLs.  I can write a spec that requires a function named "functionWhatever(string data)" in the DLL, but I have no way of knowing the dll name.  So, do you, per chance, have more info on how to implement this?

Thanks
0
 
vascovCommented:
The user specified DLLs can be in managed code ? If you are still specing, make it so that they write MANAGED code. It will simplify your life (and your users) a lot.
Here are some examples:
http://msdn.microsoft.com/msdnmag/issues/03/10/Plug-Ins/default.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/searchforplugins.asp

If they could, that would be a lot easier. Then it could all be acomplished with reflection which would end up being a lot more flexible and robust
If they can't, and if you really have to use that mechanism, i advise you to just take a look at the PInvoke docs.

If you go down the managed cpp road, then you'll need to call LoadLibrary, then GetProcAddress, marshall the parameters, call the function, unmarshall the params, get back to managed code...
Here's an example of the Cpp part: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/using_run_time_dynamic_linking.asp

The generation of some C# stub that you would customize on each run is also a possibility (as is generating code on the fly with reflection.emit, but probably a lot more work...)
Personally, i would probably just use a C# file, save it, compile it and load it... (well, i wouldn't use a DLL entrypoint at all, but if i did...)

As a side note, note that you should encourage your users to use few DLLs. Loading a DLL into your address space takes disk/io, cpu, mem and address space.

hth

Vasco
0
 
grayeCommented:
There is a way to do this... but it's a bit messy.

Let's say that you know in advance the "signatures" for the public methods and properties in the external DLL.  You could create a generic DLL class module that contained those empty methods and properties in managed code.   You would then add a reference to this generic DLL to your C# application.  Then during execution you'd load the *real* DLL file instead of the empty generic DLL file.

This works a bit better when you're writing both pieces... because you could set the real DLL class modules to inherit from the generic DLL class module.  (That means that you'd have to add a reference to the generic DLL file again).

It's a bit of smoke and mirrors...  you'll telling the application to expect a module of some "base" class,  yet you're faking it out... and providing it a module of some inherited class.   As long as the signatures for the public methods and properties are the same in the two, your application will never know that it's not running the generic DLL file (the only one of the two that it knows about).

Here is an example of the execution phase (in VB.Net, but hey.. you'll get the point)

        Dim Assmbly As Reflection.Assembly
        Dim PlugInType As Type
        Dim ProbePlugIn As PlugInBase.PlugInBase
        Dim PlugInName, temp As String

        Try
            ' If running under the IDE, then always get the development version of the
            ' plugin DLL from it's development directory (which is a subdirectory under
            ' this developement directory).
            If System.Diagnostics.Debugger.IsAttached Then
                Assmbly = Reflection.Assembly.LoadFrom(Application.StartupPath & "\..\" & PlugInName & "\bin\" & PlugInName & ".dll")
            Else
                Assmbly = Reflection.Assembly.LoadFrom(Application.StartupPath & "\" & PlugInName & ".dll")
            End If
            PlugInType = Assmbly.GetType(Assmbly.GetName.Name & "." & PlugInName, True, True)
            ProbePlugIn = CType(Activator.CreateInstance(PlugInType), PlugInBase.PlugInBase)
        Catch ex As Exception
            MsgBox("Yikes!, can't find the " & PlugInName & ".dll plug-in" & vbCr & ex.message, MsgBoxStyle.Exclamation, "Internal Program Error")
            Exit Sub
        End Try
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now