In fact, I got a C++ (working) DLL that I want to import into my C# project to call it’s functions.
It does work when I specify the full path to the DLL, like this :
string str = "C:\\Users\\userName\\AppData\\Local\\myLibFolder\\myDLL.dll";
[DllImport(str, CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);
The problem is that it’s gonna be an installable project, so the user’s folder will not be the same (ex : pierre, paul, jack, mum, dad, …) depending computer/session where it’d be runned on.
So I’d like my code to be a little more generic, like this :
/*
goes right to the temp folder of the user
"C:\\Users\\userName\\AppData\\Local\\temp"
then go to parent folder
"C:\\Users\\userName\\AppData\\Local"
and finally go to the DLL's folder
"C:\\Users\\userName\\AppData\\Local\\temp\\myLibFolder"
*/
string str = Path.GetTempPath() + "..\\myLibFolder\\myDLL.dll";
[DllImport(str, CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);
The big deal is that “DllImport” desire a “const string” parameter for the DLL’s directory.
So my question is ::
What could be done in this case ?
Contrary to the suggestions by some of the other answers, using the
DllImportattribute is still the correct approach.I honestly don’t understand why you can’t do just like everyone else in the world and specify a relative path to your DLL. Yes, the path in which your application will be installed differs on different people’s computers, but that’s basically a universal rule when it comes to deployment. The
DllImportmechanism is designed with this in mind.In fact, it isn’t even
DllImportthat handles it. It’s the native Win32 DLL loading rules that govern things, regardless of whether you’re using the handy managed wrappers (the P/Invoke marshaller just callsLoadLibrary). Those rules are enumerated in great detail here, but the important ones are excerpted here:So, unless you’re naming your DLL the same thing as a system DLL (which you should obviously not be doing, ever, under any circumstances), the default search order will start looking in the directory from which your application was loaded. If you place the DLL there during the install, it will be found. All of the complicated problems go away if you just use relative paths.
Just write:
But if that doesn’t work for whatever reason, and you need to force the application to look in a different directory for the DLL, you can modify the default search path using the
SetDllDirectoryfunction.Note that, as per the documentation:
So as long as you call this function before you call the function imported from the DLL for the first time, you can modify the default search path used to locate DLLs. The benefit, of course, is that you can pass a dynamic value to this function that is computed at run-time. That isn’t possible with the
DllImportattribute, so you will still use a relative path (the name of the DLL only) there, and rely on the new search order to find it for you.You’ll have to P/Invoke this function. The declaration looks like this: