I am trying to link a dll to a vba project and I am going nut 'cause it fails to find it even if I am 100% sure of the path (I pasted 100 times the path from the exact position).
I called
Private Declare Function IMB_connect _
Lib "C:\Users\Andrea.GIORDANO\Desktop\API\bin_dynamic\API.dll" _
(ByVal n As String) As Long
But it continues to return me an error 53: File not found.
I don't get what would be the problem that seems so silly...
I tried with all kind of slashes '\', '\', '/', '//': no success.
FYI I linked the same exact dll within a c++ project and in that case worked well so I believe the dll itself is fine...
Your dll is probably dependent on other dlls. You can use Dependency Walker to get the full list of the dependent dlls.
The dependent dlls must be in one of the following (from msdn):
The directory from which the application loaded.
The system directory. Use the GetSystemDirectory function to get the
path of this directory.
The 16-bit system directory. There is no function that obtains the
path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get
the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable.
Note that this does not include the per-application path specified
by the App Paths registry key. The App Paths key is not used when
computing the DLL search path.
If you are running a VBA project, probably Excel.exe is loading your code. This means the dependent dlls of your API.dll must be in one of the directories in the quote above.
Please note that placing dlls in the system directory could affect the functionality of other applications in the system. (read about dll hell).
Related
I am installing a package manually on my own system because I need to make some changes to it that aren't available in the basic version in my package manager. I also am trying to keep packages installed locally if possible, so I'm installing it with prefix=$HOME/.local instead of the more common prefix=/usr/local.
When I do this, I have no problem executing the program from my terminal, because I added ~/.local/bin to my PATH and the package was installed with relative paths to its shared libraries (i.e. ~/.local/lib/<package>). Executing from the command line is no problem, but I want to be able to access it from the favorites menu in gnome, and for that I need to make use of the <package>.desktop file.
I could hard-code the path to the executable in the .desktop file itself, but when I pull a later version down and re-install it, I'll have to redo those steps. I was wondering if there's a way to avoid that.
I've tried symlinking the executable to a directory where .desktop files do have included in their path, and the application is correctly treated as a GUI option, but launching the executable results in an error trying to find a shared library. I think this has to do with how cmake handles rpaths, which to my understanding is a way of relatively linking executables with their required libraries.
I think what I want to do is have PATH inside a .desktop file include ~/.local/bin, without changing the .desktop file itself. Can I alter the 'default' path used in accessing a .desktop file?
The answer to my question was found in the Archwiki:
Specifically, I needed to add ~/.local/bin to my path in ~/.xinitrc. Now my graphical programs work as expected.
When I try to load a .dll then the application first try to load the .dll from their local folder, if it is not there they try to load it using the %PATH% environment variable.
I don't mind if the OS is doing any other searches, but I am interested in the order of the search in the %PATH% environment variable.
Now, let's assume I have two versions of theis dll, and both pathes of those dlls are in the %PATH% environment variable.
Am I guaranteed that the first path that is containing the .dll in the %PATH% environment variable, is the path which the .dll will be loaded from?
10x.
There is exact order in which DLL is searched.
Checkout this:
http://msdn.microsoft.com/en-us/library/7d83bc18%28v=vs.80%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx
UPDATE:
Windows will search in order as they appears in PATH variable.Please note, that full PATH variable consist from 2 parts:
System : HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PATH
Then is appended current user's PATH : HKEY_CURRENT_USER\Environment\PATH
Is it correct that mydll.dll which is located in the GAC will read mydll.dll.config from the the same path that it is effectively called from? As an example, if myprogram.exe runs in c:\test, all I need do is copy mydll.dll.config into c:\test and all will work OK?
In replies to a similar question, mention is made of setting the location of the config file via code using AppDomainSetup.ConfigurationFile. Given the dll is not a standalone executable, it doesn't have a load event or an entry point so where are you supposed to enter that code. I to presume that I can/must create a public static method that sets the location and that method must be called by my executable before actually using the dll?
On linux, we have LIBRARY_PATH and LD_LIBRARY_PATH environment variables in order for programs to search for libraries. Do we have similar thing on windows? Particularly Windows 7?
Also, I would like to know best practices for DLL use (where to put them, use envs or not, etc.), since I want to work on windows like everyone does, and not to sloth myself on workarounds :)
Edit: As explained by Bob, this answer describes the Alternate Search Order, which is not what most applications would see. The full rules are quite complex. I don't think I can summarize them here. Instead, read the Microsoft docs - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
My original answer was:
This MSDN article explains the default search order. I quote:
The directory specified by lpFileName.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
In (1), if you statically linked against the DLL's stub library, I think "the directory specified by lpFileName" is the process's exe's path.
Take a look at the help for the LoadLibrary and CreateProcess functions. These describe the paths used to locate DLLs, and how you can modify them.
It looks on currentDir first then WinDir and SystemDir also in your path
According to what #andrew has mentioned in his answer, the order of folders that are used on Windows to search a DLL may be different from one configuration to another. I think the simplest way to check this order on Windows is to use the Dependency Walker tool. After opening the tool, and pressing the "Configure Module Search Order" button on the toolbar, you will see a window like this:
This window shows you the current search order on your machine. The interesting part is that by pressing "Expand", you can see the whole folders in the search path one by one. You may also change the order if you want, to be used for loading an specific module.
I have Raize 3.0 installed in D2007. For whatever reason, I can't seem to get the Ctr-click to work for loading up it's units, even though that feature works fine on all my other Delphi and Third-Party components.
Here's what I have for Raize on the Library Path:
$(ProgramFiles)\Raize\RC3\Lib6
$(ProgramFiles)\Raize\RC3\Source
...and the Browsing Path:
$(ProgramFiles)\Raize\RC3\Source
Lib6 contains *.dcu and *.dfm files, and Source contains, obviously, the source code. Adding Lib6 to the Browsing path doesn't seem to affect things one way or the other.
I don't get why this Ctrl-click unit-loading feature isn't working, just for this one component. Any ideas what I may be missing?
You shouldn't need Source path in your Library path. Lib6 should be added to Library Path, and Source to Browsing Path.
If you do so, and it still doesn't work, then you have a similar problem with me:
Problem with setting Browsing Path in Delphi option page
For lib path you generally don't need source files. I use:
C:\Program Files\Raize\RC4\Lib\BDS2007
For browsing path you need to specify the language directory, e.g.:
C:\Program Files\Raize\RC4\Source\Lang\English
If this doesn't fix it, does your unit compile without errors?