tags:

views:

258

answers:

3

Hello every body:

I have a DLL made in Delphi 7/Windows XP that I want to statically load in a host application on Windows (made in Delphi, too). I am using this line of code:

procedure Prepare_HTML_Email(var MailMessage : TIdMessage; const FileAddress, aDetail, aAlarmType : String); stdcall; external DLL_ADDRESS;

where DLL_ADDRESS must be the location the DLL is. But at this point I have a problem. The host application is a service, so it is running in C:\WINDOWS\System32, but I want to put the DLL in another directory, not in C:\WINDOWS\System32. The "external" keyword doesn't let to follow it with a function, it only admits a constant expression. So, How can I get the path of the DLL????

+4  A: 

First, you're not "statically loading" anything. The D in DLL stands for dynamic; all DLLs are linked dynamically, no matter what. Static linking is how DCU and OBJ files get included in your program. You can't link statically to a DLL.

You're talking about load-time dynamic linking, where the OS loads the DLL for you implicitly due to the functions listed in your program's import table, as opposed to run-time dynamic linking, where you call LoadLibrary using whatever you want. When you use the external directive to define your function, you create an entry in the import table, and as far as I know, relative paths there are meaningless. The OS looks for DLLs at load time (and run time) using a certain documented search order. In general, it's the application's own directory, the current directory, the system directory, the Windows directory, and then everything else on the PATH environment variable.

In your case, the current directory and the system directory are the same place, and you don't have any control over them anyway. Don't put your DLLs in the Windows directory; that already has enough stuff that doesn't belong there.

Your best bet is to put your DLLs in the same directory as you've put your service EXE. If you don't want then, then you could put just enough to bootstrap your program in one DLL in that directory and then load everything else later with LoadLibrary using whatever private DLL directory you want.

You could put your DLLs someplace else and then add that directory to the PATH environment variable. That variable is a shared resource, though, so think twice before you change it.

Rob Kennedy
I believe it processes only the current directory and the path...which is why %SystemRoot%\system32 is added to the path by default.
skamradt
Gee, I figured the system directory is added to the path so you can run programs in that directory without needing the full path. Please see the linked documentation. I suppose it would be easy to test: Edit your path to remove that directory and see what breaks.
Rob Kennedy
The "documented search order" described in the link would appear to be quite clear and definitive. Current directory is the *first* folder looked at, the path folders are that *last* folders to be checked. In between are a number of system defined locations that are checked. My guess is that the system directory is added to the PATH variable by default to support applications that don't implement OS-equivalent file searching and (incorrectly) assume that the PATH variable is definitive. But that's pure speculation.
Deltics
+1  A: 

If you place the path to the DLL in your system path, then it doesn't matter where you put it. Just be aware that you will have to reboot if you make the change for a service before it may take effect.

To edit the path variable, go to the advanced tab for system properties (right click properties from "My Computer") and press the "Environment Variables..." button. Change the system variable "Path" to include the directory where you want to store your DLL.

When resolving a DLL, the system first checks the current directory where the process is started, followed by the path variable from left to right, and will use the DLL found in the first directory it runs across... which is why it works when you place it in C:\Windows\System32.

skamradt
A: 

See how Windows load DLLs here:

http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx

SetDllDirectory() may help you, but it's not available before XP SP1.

ldsandon