I am currently trying to basically expose a native C++ library, that I not have the code for, as a WebApi. To do that, I created a managed C++ wrapper library, that allows my web application to communicate with the native code.
So the dependencies of the project look something like this:
Web application (ASP.NET)
Managed C++ Wrapper
Native C++ Library (DLL)
Native Dependencies (DLLs)
My problem is now, that I always get the error message "Could not load file or assembly [ManagedWrapper.dll] or one of its dependencies. The specified module could not be found."
Since the managed wrapper library is in the same solution, it is listed as reference and even copied to the shadow copies, so I assume that the problem lies in the native dependencies. I am well aware that there are problems with loading native DLLs in ASP.NET as no shadow copies will be made of them and they can not be added to the GAC. I tried to tackle this problem by just adding them to my %PATH%, but the error still remains. Dependency walker did not show any additional dependencies and adding the native DLLs to system32/inetsvr fixed the problem, but this is obviously not the way this should be done.
So here my question: What could be the reason that the PATH variable is not working? (And is there maybe another way to get this to work?)
Using loadLibrary to load with an absolute path is not really a possible solution as I have no influence on the native C++ library and how it will load further dependencies.
I think I found my own a solution to my problem and hope this might help someone else as well:
My native DLLs where somewhere in my home folder. Moving them to a more accessible place, i.e. C:\temp\, and adding this folder to the path seemed to do the trick. My guess is, that this was a permission based problem, even though I added rights for IUSR for that folder in my home directory before.
Related
I am currently working on a C++ gui application. The application uses the Python/C API to call some python scripts. The scripts are located in the solution directory, and I call them by simply providing the path. This is currently working fine while debugging the application or even running the generated .exe file, but I am wondering how this could work if I want to release and distribute the application onto a different computer for someone to use. How can these scripts be deployed with the application?
I also have a .ttf font file with the same situation. How can this resource file be deployed with the application?
In other words, I want to deploy/release a C++ application with the scripts and resource files.
FYI: the C++ application is a Visual Studio project.
Thanks for the help in advance, and let me know if any more information is needed!
Update:
I just wanted to clear up the way my project is working currently:
PyObject* pArgs = PyTuple_New(5); // I setup the arguments the python function needs
PyImport_ImportModule("requests"); // imports...
// make python call
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
So this is (for the most part) how I call the scripts with the C++ source code. The scripts are located in a folder that is located in the solution directory.
I hope this explains my problem a little better.
Update:
Just another little update... Using some answers to other similar questions got me to the following point:
I need to obtain a python library, compile and link it with my C++ application, and then bundle the dependencies with the application (How to distribute C++ application which calls Python?)
So I guess my question is now shifting to how I would be able to get this done. What are the specific steps to do this? I also got a link (https://docs.python.org/3.5/using/windows.html#embedded-distribution) to an embedded distribution of a python environment (maybe this should somehow be used?). Also, I am able to statically link python into the application. I just don't know how to bundle and deploy the scripts I created and use in the application.
PyImport_ImportModule("requests")
The parameter is "requests".
Put the py file aside exe file when distributing.
So, you need to make sure that the C++ application can still access the python libraries when its released and those libraries/dependencies arent necessarily available on other systems.
You'll need to, like another commenter suggested, use one of the importing modules utilities, like PyImport_ImportModule("library name").
You can see these utilities here: https://docs.python.org/3/c-api/import.html
You'll also need to either
Put the libraries that you want with the exe (in the same directory) or
put them in the system environment path ( which is probably less straightforward).
Hope that helps and that I understood you're question correctly.
I'm lost here and I have no clue how to proceed. This is not a question about how to make my program work, this is a question about how to stop wasting my time.
My programming environment is Visual Studio 2013 on windows, in C++.
I use 3 libraries extensively, namely: boost (using dynamic linking), OpenCV, and Qt.
During the development, I have configured VS to look at those 3 libraries by default for include and .lib. I have also added the 3 folders containing all the dlls to my PATH environment variable.
It works, but it is sometime painful, let me explain you when.
First hassle: Anytime I have a LNK error telling me I miss a function, it is usually on OpenCV since it has only one include file referencing all the functions. I have to look at OpenCV's source code to see what module this function belongs to and to know what I must link my program to.
Second Hassle: When comes the time to deploy my application, I have to ship it with all the relevant dlls. To know which one I need, I open dependency walker and try to forget nothing, I have then to test it on a different computer because 102% of the time I have missed a couple, and then I have to configure my Installer generator to include all those one by one.
Third Hassle: To ease a little bit the process of configuring a new development machine, I have recently switched to NuGet. It is great, I add boost with a couple of clicks to any project. But now my boost DLLs are everywhere, I have one folder per boost library, and since there are dozens of those I can't even add them all at once to my PATH now, so I have to move them manually to the appropriate folder, and that is really not what I want to do with my not-so-precious-but-who-are-you-to-judge time
I have looked around and couldn't find any good practice regarding this issue, maybe because they are too obvious, or too specific to a particular setup.
How do you do? How would you do if you were me?
We put all our external dependencies in version control along with the code. This ensures that all code can build "out of the box" on any of our development machines and also ensures that for any given version of the code, we know exactly which dependencies is has.
The best way to check for missing dependencies is how have a good automated test suite, if you've got comprehensive converge then if your tests pass you must have deployed the required libraries.
In terms of linking to the appropriate libraries, unfortunately, that just sounds like an issue with the structure of OpenCV (I'm not familiar with OpenCV). I tend to use dumpbin under Windows and nm under Linux to easily grep for symbols when I get link errors with an unfamiliar library.
I have created a simple application in Qt5 but, when run that application in for example windows 7, tells me the dll file something is missing, and another dll and another dll.
Now I want a package that contain all dll files that any Qt application needed.
Or, What's the Important dll files that needed to work any Qt application ?
Or, What's the Important dll files that needed to work any Qt application ?
In general, the Qt modules that you are using. If you use QtSql, you need to have the corresponding dll, but it goes the same way for any module. As for a simple core application, you would need to have the QtCore dll, respectively. I could continue the enumeration, but I believe you see the pattern how it goes.
Going even a bit further, you would need to specify your dependencies in the LIBS variable if you happen to use qmake. That is also a place where you would already need to be aware of your direct dependencies.
It would be usually the single library name, but in complex cases, you can always read the documentation of the project. The main point is the fact that you need to get aware of this without debugging. The latter would be more like an after-thought.
There are no "hidden dependencies". Since you are coding the project, you know the dependencies that you use. You will need to ship them.
There are some odd and rare cases when issues come that you would not be aware of, like missing dll for a different machine having a distinct VS/MSVC setup. In that case, it is better not to ship all the dlls for each possible end machine, but the end machine is supposed to install redistributable packages.
In rare cases when the above does not suffice, you can check the error message. If that is still unclear, you can use introspection tools for debugging the issue, like dependency walker.
Disclaimer: this answer goes as broad as the question is.
My basic issue is this: my program (MyProgram.exe) has a dependency on a DLL from another program (OtherProgram), and I'm trying to avoid repackaging a new DLL every time OtherProgram updates. I'd like to have MyProgram.exe link in OtherProgram's DLL when it launches, but I'm not completely sure that Windows allows for this. So if there is some kind of workaround that would also be acceptable.
And just for some background, the platform is Windows 7 x64, and MyProgram.exe runs fine when I create a symlink in the MyProgram.exe project directory to the DLL in OtherProgram's install directory. When I try to run it without the symlink, I get the "program can't start because OtherProgramDLL.dll is missing from your computer" error.
Any advice or links to relevant info is greatly appreciated!
EDIT: Clarification: the DLL is not linked at compile-time, this issue crops up at runtime
There are two types of dynamic linking in the Windows world:
Load-Time linking is when a DLL is loaded automatically when your program starts up. Windows finds this DLL using a specific algorithm I'll discuss below.
Run-Time linking is when you specifically load a DLL by calling LoadLibrary in your code. Similar rules apply as to how the library is found, but you can specify a fully-qualified or relatively-qualified path to control the search.
In the case of Load-Time linking, MS recommends that your program's DLLs are stored in and loaded from the same directory where your application is loaded from. If this is at all workable, this is probably your best option.
If that doesn't work, there are several other options, outlined here. One is to leverage the search order by putting the DLL in either the working directory or the directory where the application was loaded from.
You can change the working directory of an application by:
Create a shortcut to your application.
Bring up the shortcut's properties
Edit the "Start in" property with the directory where the DLL is located.
When you launch your application using the shortcut, it will load the right DLL.
Other options for load-time linking include:
Adding a manifest to your application which specifies where your dependent assemblies are, or,
Setting the PATH.
You could use LoadLibrary, but you would need a way to guarantee the DLL's location. This Wikipedia article provides good example on how to use the DLL after it has been loaded.
You can add the directory where the dll is located to the PATH environment variable.
I have struggled with the same problem and also found a dead end with the suggested methods like LoadLibrary, SetDllDirectory, Qt's addLibraryPath and others. Regardless of what I tried, the problem still remained that the application checked the libraries (and didn't find them) before actually running the code, so any code solution was bound to fail.
I almost got desperate, but then discovered an extremely easy approach which might also be helpful in cases like yours: Use a batch file! (or a similar loader before the actual application)
A Windows batch file for such a purpose could look like this:
#echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>
/edit: Just saw #SirDarius comment in Luchian's answer which describes that way, so just take my batch code bit as a reference and all credits go to him.
I have the same problem with one application I am working on.
I do not want to use runtime loading because there are tens of functions I would need to manually create function pointer for.
Mr Dibling's mention of manifest file opened a new door for me but I sadly found out that the oldest version of windows that supports the feature is Windows 7. It won't even work on Vista.
Long story short, a friend familiar with Windows Application development told me to look up Delay-Loaded DLL, which turns out to solve the problem perfectly with minimal effort. It delays the loading of DLL library to either the point you manually do, or the first time its function is called. So you just need to add your DLL path to the search path before that happens, where SetDllDirectory helps.
Here is the steps to make it work:
1) Specify the DLL to be delay-loaded to linker, either through your makefile, cmake or VS property page (Linker->Input of VS2015)
2) Call SetDllDirectory at the beginning of your program, before any call to the DLL is made.
Delay-loaded DLL is supported all the way back to VC6.
SetDllDirectory is supported after XP SP1.
Use Symbolic Links to the 3rd Party Executables
I found the approach advocated by Aaron Margosis useful. See:
Using NTFS Junctions to Fix Application Compatibility Issues on 64-bit Editions of Windows
Essentially, create symbolic links to each of the dependent 3rd Party executables. Place these symbolic link files in and amongst your own dependent executable files. Except for filename changes to the targets, the 'soft' symbolic links will resolve the load-time dependencies even as the target of the links are changed by future updates.
I am working on a Qt DLL that is used as a plugin for a large application. This DLL depends on other DLLs that are sadly not located in the same folder and hence will only load if the current working directory has been set correctly (which the large application does prior to calling LoadLibrary on the DLL). I have no control over this behaviour.
I have been asked to add a simple COM object to this plugin which I have done but I now have the problem that the DLL cannot be registered or used by a 3rd-party application unless the current working directory is set correctly - because any LoadLibrary calls on the plugin fail due to the missing dependencies. Obviously I have no control over the current working directory used by 3rd-party apps and at this stage I am not allowed to modify the PATH to ensure the dependencies can be found.
I have tried using /DELAYLOAD for the dependent DLLs but this fails with 'cannot delay-load foo.dll due to import of data symbol...' errors. Again, I cannot easily change the way these dependent DLLs are used.
Currently I think the only solution is to move the COM object into a stand-alone DLL that doesn't depend on anything else but I am under pressure to find a solution and leave the COM object in the plugin DLL. I can't see how this is possible so I thought I'd see if anyone else has any ideas. Some form of system-wide SetDllDirectory call would help or some registry hack that could set the working directory when a 3rd-party app calls LoadLibrary on my plugin.
IMO separating the COM object into a separate .dll is the cleanest solution - anyone would expect an in-proc COM server to be registered by using regsvr32 and that requires no fancy dependencies in that COM server.
I don't know if it's precisely a solution to your problem, but maybe this can help you: try to look at the possibilities offered by manifest files. I hope it will help.
You could use a runtime registration model.
The Dll could register itself as a COM server in its own initialisation code.
This only requires that loadlibrary is guaranteed to be called before the dll is used as a COM server.