views:

860

answers:

3

I have a DLL that I need to access methods from.

In most cases like this I just use [DllImport] to access methods from unmanaged assemblies, but the problem with that in this situation is that it requires the path to the DLL at instantiation time, so a constant string.

This particular DLL is one that gets installed with my application and I can't guarantee where it will be after the program is installed (I'd rather not put it somewhere static like %SystemRoot%).

So is there a way in C# that I can declare and use a method from a DLL at runtime with a variable path?

Any ideas or suggestions would be greatly appreciated!

A: 

put the path in the registery during install and call it out before loading the dll

jmcecil
I don't see how this helps me, getting the path to the dll at runtime isn't a problem. It's declaring the function in code, using that dynamic path, that I'm trying to figure out.
Mel Green
+1  A: 

Don't use a path at all. Windows uses a default method of searching for DLLs when trying to dynamically or statically load a function from it.

The exact search logic is documented at MSDN in the docs for LoadLibrary - basically, if the DLL is just used by your app, put in the same folder as your application during the install and don't worry about it. If it's a commonly used DLL, put it somewhere in the folder structure searched by LoadLibrary() and it'll get found.

Ken White
In this particular instance I'm unable to put the DLL in the same directory as my application, it's in a sub-directory of my app and I'm trying to use a relative path to declare it. Which works on some machines, but isn't consistent. =\
Mel Green
Try importing SetDllDirectory from Kernel32 and call it setting Application.StartupPath.I'm going to try this with a project of mine at home when I get home today and I'll comment back when I test it.Hope that helps
Zack
@Zack: That sounds like a good idea, I'll give it a try.
Mel Green
That's rough. The only two possibilities I can think of are to add the path to the DLL to the system PATH during your install, or to write unsafe code to manually use LoadLibrary() and GetProcAddress() dynamically at runtime. Maybe someone else has better ideas, though.
Ken White
Better ideas, like Zack's. :-) Nice job.
Ken White
Thanks for the ideas Ken and Zack, sadly after further investigation I think I might have a bigger problem on my hands, since the DLL in question won't load even when placed in the same directory as my app (on this particular machine), so I've got some more debugging before I come to a solution.
Mel Green
+2  A: 

This is a bit of hack, but since you say that you can find the path to the dll at runtime, why not copy it to your current working directory before you use any of the functions? That way, the dll will exist next to your exe and will be found by LoadLibrary. No need for any additional path in your DllImport.

The only other way to use a method from a dynamic path is to do this:
1) Do the necessary P/Invoke signatures for LoadLibrary & GetProcAddress
2) Load the library from the desired path (LoadLibrary)
3) Find the desired function (GetProcAddress)
4) Cast the pointer to a delegate Marshal.GetDelegateForFunctionPointer
5) Invoke it.

Of course, you will need to declare a delegate for each function you want to "import" in this way since you have to cast the pointer to a delegate.

Erich Mirabal