I have built Game Music Emu from source to use with Love2d. (Note: I am not very familiar with C/C++.)
In lua I load the dll with FFI and on my computer it works great, but when I sent my friend the app for testing, his machine doesn't recognize the DLL.
I sent him the love2d binaries with the libgme DLL included to make sure he didn't just misplace the DLL file. So what he is running is the exact same thing I am running.
My code looks like this:
ffi.cdef[[ ... ]]
local gme = ffi.load("libgme")
This is the exact error my friend gets:
lovegme.lua:4: cannot load module 'libgme.dll': The specified module could not be found.
Depending on how libgme is compiled you may have some dependencies that are satisfied on your computer (for example, mingw libraries), but not satisfied on the other computer.
I'd try several things: (1) use the full filename in the load command, (2) use "profile" mode in dependency walker to check what is failing during DLL load, or (3) use the same dependency walker on your machine to see what other DLLs libgme may depend upon and include those in your package/installation as well.
Related
I've dynamically linked libhunspell.dll (HunSpell) to my application. It works, but there is a dumb problem which I don't know why it happens.
Even before I use LoadLibrary("path\\to\\libhunspell.dll"); to load it and use it, on the start of the application it attempts to load the library by itself. If I place the libhunspell.dll into the path where my main executable resides, it can load it, otherwise it reports an error, immediately after starting the application - This application has failed to start because LIBHUNSPELL.DLL was not found. Re-installing the application may fix this problem. and the application doesn't start.
I would understand if the LoadLibrary would use invalid path but this happens as soon as the executable runs, even before the first statement in WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) executes (I've tried to place a breakpoint and it doesn't even reach it, so this happens before).
So, as a result, I must place libhunspell.dll in the same folder as my application executable, and not in the path I want.
This is probably easy to fix although I don't what to look for.
So the question is - how do I avoid it loading it immediately and have it wait until I use LoadLibrary call?
Here is how I linked if it can help:
1) compiled libhunspell.dll in Visual Studio 2015 (I used /MT option to link it statically so it doesn't have VC++ Redistributable as a dependency).
2) created import library (libhunspell.lib) using implib.exe -a -c -f libhunspell.lib libhunspell.dll
3) linked that to the source .cpp unit which is using it using #pragma comment(lib, "libhunspell.lib") (it is RAD Studio 2010 so the .lib is required unlike newer versions).
4) later in the same .cpp used LoadLibrary to load this library and used it.
By linking in the import stubs (libhunspell.lib) the OS will load the DLL for you as it is now a static dependency.
One approach would be specify the library as a delayload dependency: /DELAYLOAD:libhunspell.lib via the linker options. You can then call LoadLibrary on the DLL.
The only other option is to stop including the .lib in the linker step, making it truly a dynamic dependency.
I assume you did Add to project a *.lib file for your DLL. That is a kind of "static" linkage done in the App initialization (prior to your forms are created). So it has two disadvantages.
You DLL must be in the same path as the Apps EXE file
Sometimes DLL file name is locked (can not be changed)
The advantage is that you do not need to do any coding for the DLL loading as the VCL do it for you ... so your app should not contain the LoadLibrary,GetProcAddress calls you just include the *.h file with propper import declarations ...
For dynamic linkage you need to remove the *.lib from your project and use WinAPI LoadLibrary + GetProcAddress for loading your DLL as josh poley suggested. Here an example:
Builder C++ calling VC++ class
Beware there was/(is?) a bug in the GetProcAddress preventing from loading all the functions from your DLL in some cases. Especially if the DLL has old legacy mangling of names the count of functions is high and the DLL was created on compiler incompatible with the mangling in question.
I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL
I send a Racket executable(in a distribution package) to a few friends and they get the error:"Failure: can not load the DLL". On my computer it runs without problems. It's using the rsound package.
Yes, good point. Currently, rsound is hard-coded to look in the collection path for the DLL. That won't work for programs compiled into executables. I've just updated rsound to tell it to look in "standard locations" as well for Windows and Mac.
Try this: Using the DrRacket package manager, update your copy of portaudio. When you're done, it should be at version "b9403a6dfbfb5eadf824ed91731ec141bf363677".
After this, it should be possible to pass along the executable file and run it, as long as the two required dll's are in the same directory as the executable. These two dll's are:
portaudio.dll
callbacks.dll
For windows, you'll find both of these in a subdirectory of the portaudio package. Finding these is going to be a teensy bit of a hassle on Windows; I believe these get installed in your user directory\RoamingData\\portaudio\lib\win32\x86_84\3m\ . If the target computer is a 32-bit machine, you'd substitute 'i386' for 'x86_64' in that path.
I know that Windows can make it quite hard to find the files you're looking for; let me know if you have any trouble.
Whew!
I'm having trouble getting executables compiled from Haxe source to work on computers that don't have Haxe installed. The problem first appeared with a simple networking program but it seems to come up for any program at all. Even something like
class Test
{
static function main()
{
trace("test");
}
}
compiled to an exe with haxe -main Test.hx -neko Test.n and nekotools boot Test.n will run on my computer but on anything else gives a neko.dll is missing from your computer error. I get a similar error if I compile the haxe source to c++ or c# and run the generated exe.
I'm not sure what neko.dll is, but I don't see how it should be required for the exe to run. I feel like I must have some basic misconception! Is this intended behavior? How can I compile Haxe code so that it will run on any windows machine without installing neko?
neko.dll is normally located at C:\HaxeToolkit\neko. You may just copy and paste that next to the exe.
Generally when distributing a exe, you have to also distribute the required dlls. You can check the dll dependency with various tools. For example, using Dependency Walker, open the exe by it and it will list out the dlls. Right click a dll item in its menu and select properties, there you will find where it locates.
I am using heat to harvest the COM dll and tlb files (let's call them MyLib.*, developed in VB.NET) to do the COM registration. Everything was working fine, when I install MyLib.dll and MyLib.tlb into my application's installation folder, i.e., INSTALLDIR. However, since we want to allow different versions of our SW to be installed on the same machine, and if they are using the same version of COM component, only one copy of the dll (I think each version of our SW should have its own tlb, please correct me if I am wrong) should be installed, we now want to install MyLib.dll into another folder, specifically PROGRAM_FILES\Common Files\SHARED_FOLDER_NAME, so now if one version of our SW is uninstalled, the MyLib.dll will not be removed and can still be used by other versions.
But here comes the problem: my COM registration is just simply not working any more after I install this dll into this another folder, and it keeps saying that can't find file specified when I am calling the COM function which indicates registration failure. In the WIX installer project, everything is the same except this folder for MyLib.dll.
Here is the registry structure after installation:
Firstly I have HKCR\CLSID{MYCLSIDs}, each of them represents one of my COM class. in the sub-key named "InprocServer32", I have Assembly, Class, CodeBase, RuntimeVersion, threadingModel. And the CodeBase is either common file folder (not working) or MyApp's installation folder(working), which is the different locations I put the dll. I thought there would be another sub-key TypeLib under {MYCLSIDs}, since Access only sees the TypeLib and I think there should be some link from the TypeLib to the actual dll, however, at both cases this sub-key is missing but in the second case it is still working. Is there a problem of it?
Secondly I have HKLM\Software\Classes\CLSID{MYCLSIDs}, these keys are of course the same structure as described above.
Thirdly, the HKCR{MYPROGIDs}, these are just ProgIDs of my classes
Fourthly, HKCR\Typelib{LibID}, which includes the information from tlb file, and this ID is from the Assembly GUID of COM component project.
Finally, the HKEY_CLASSES_ROOT\Interface{InterfaceID}, there is sub-keys named ProxyStubClsid32 with value {00020424-0000-0000-C000-000000000046}, and the one named TypeLib and the value is my LibID.
As I mentioned, the only difference is the CodeBase, which stores where MyLib.dll is located. In order to verify that, I did two tests: after I install MyLib.dll into the shared folder, the COM calling fails. But if I replace all the CodeBase values for SHARED_FOLDER\MyLib.dll to INSTALLDIR\MyLib.dll, and copy MyLib.dll into INSTALLDIR, it actually works. Vise versa, after I install MyLib.dll into INSTALLDIR(in which case COM is working), I change the CodeBase values from INSTALLDIR\MyLib.dll to SHARED_FOLDER\MyLib.dll, and make a copy to SHARED_FOLDER, this time it fails. So it seems that it is exactly the installation location's problem, which is the opposite to my understanding of COM. And I don't think there is a permission issue for the SHARED_FOLDER(I could be wrong) since it is in a folder that my installer creates.
Please help, thanks!
It turned out that MyLib.dll is using some other libraries, which are still installed in the MyApp installation folder. And so in that case that MyLib.dll is installed in the shared folder, it tries to find those libraries in the same libraries, which of course fails. When I install those libraries in the shared folder too, it is working.
BTW I found fulogvw.exe very helpful when tracking down the assembly loading problem. For example in my case in the failed log it says can't load file xxx.dll in SHARED_FOLDER, the xxx.dll is some library that MyLib.dll is using, and I had no idea that MyLib.dll needs it until I see the log.