How to load/debug a Mono Assembly.LoadFile BadImageFormatException on Mac? - macos

Summary:
I'm trying to manually load an Assembly in a Mono environment and getting a BadImageFormatException on Mac, but it works fine on Windows. Since Mono is running inside another app, I'm not able to run the app from the command line with debug enabled to get better logging.
Detail:
I wrote some plugins for the Unity3D editor in C#. They have been working for both Mac and Windows for more than a year. I'm now trying to change the way my plugins are loaded from Unity's default "Plugins" directory by loading them manually when my class is called for the first time from another directory (which is in the PATH variable). On Windows I simply call Assembly.LoadFile and it all works fine as before. On Mac, I'm getting a BadImageFormatException error. I thought it might be related to the fact that on Mac the plugin is a bundle.
I tried:
Assmebly.LoadFile("MyPlugin")
Assmebly.LoadFile("MyPlugin.bundle")
Assmebly.LoadFile("MyPlugin.bundle/Contents/MacOS/MyPlugin")
The first one (just the file name) returns a FileNotFoundException. The other two return BadImageFormatException making me think it found it but something else is wrong.
Is there a way to get more info on what's going wrong? The FusionLog member of the exception is NULL since it's on Mac, I only get the basic message.
Do my plugins need to be built differently somehow on Mac to be manually loaded like this?
Thanks,
Brett

Assembly.LoadFile takes the path to a .NET assembly.
This means that MyPlugin.bundle will not work, because it's a directory.
Regarding the last option, that file (assuming it's a file and not a directory) needs to be a .NET assembly - one way to check if that's the case is to run the file tool from a Terminal window:
$ file MyPlugin.bundle/Contents/MacOS/MyPlugin
and it should respond something like this:
MyPlugin: PE32 executable for MS Windows (DLL) (console) Intel 80386 32-bit Mono/.Net assembly
My guess however is that it's not a .NET assembly, but instead a native (OSX) binary (among other things because .NET assemblies usually have .dll extensions).

Related

"flutter run -d windows --release" works but executable doesn't

I do have a strange behavior with a flutter package I am building. It uses FFI to integrate a custom-made c++ library.
When I run flutter run -d windows --release the code starts and I do have the window with the code running.
However, when I go to the directory where the executable is stored and I run it, the program starts but the library is not loaded. I do see also that when I run flutter test, it complains that it cannot load the library. I have checked that the dll's needed are there using dependenciesGUI.exe and it seems that everything is fine, at least on my side. I do see however that within kernel32.dll I am missing ext-ms-win-oobe-query-l1-1-0.dll.
I am using Visual Studio 2022 with the x64 configuration.
Any idea on what could be the issue? For me it is VERY puzzling to be able to run the software through flutter but not with the executable directly.
Thanks!
Yours,
Pi-r
EDIT:
I compared my package with a fresh package built with flutter. With a fresh package, the behavior is the one expected: I can have the program run normally or with flutter run.
I compared the libraries of the clean package with the ones linked in my package. They are the same (with the same missing dlls which do not seem to pose an issue).
I also checked that the exported functions I needed where present -> It is the case.
The only difference I can see is that using flutter run adds a series of libraries to the path. Has I am a Linux person, I do not know of a tool that could be used to detect what is the missing library. I am open to write a separated c++ code that would load the library if it could help me identify what is the issue... ANY tips/tricks would be greatly appreciated :)
I finally found the issue I had and it is related to a different behavior under Linux and under Windows (as you will guess, I am a Linux person).
When compiled under Linux, I can force the compiler to link multiple libraries relatively to my main library. I discovered that this is not the case under Windows. Either the dlls are in the executable folder or in the Path.
For the sake of code clarity, my package uses two different libraries. Library A, which is compiled from flutter with the ffi package, called library B. First the second library was in the asset folder and with the relative linking of Linux, it was working perfectly. But it did not work under Windows until I explicitly copied the two in the same directory of the executable.
The solution was then to ensure that both libraries are copied correctly in the directory of the flutter executable. This can be done easily if you add the dependent libraries to the bundle variable in the CMakeLists.txt of the package.
However, this doesn't work when you do the testing (flutter test). As the bundle mechanism seems to be not propagated to the test function. Therefore here, the only solution is to copy the dependent libraries to the root directory of the source code :vomiting_face:
I must point out that this is only the case under Windows, for Linux, it works out of the box...

Qt 5.2.1 with MinGW 4.8 32bit wont run applications on Windows 8.1

Using Qt Creator 3.0.1, Qt 5.2.1, MinGW 4.8 32bit on Windows 8.1 64bit, I am able to build an application but not run it.
When trying to debug the application (new clean project), the output tells me
This application failed to start because it could not find or load the
Qt platfor plugin "windows". Available platform plugins are: minimal,
offscreen. Reinstalling the application may fix this problem.
follow by a
Runtime Error!
Program C:\Qt\Qt5.2.1\test\debug\test.exe
This application requested the runtime to terminate in an unusual way
etc...
I tried adding the qwindows.dll's under my /debug/platforms/*.dll but no difference there.
Is my problem due to my Windows installation?
EDIT: After trying out #paulm's solution, putting the windows dll's inside plugins instead, nothing changes.
Dependancy Walker tells me that I miss
API-MS-WIN-CORE-KERNEL32-PRIVATE-L1-1-1.DLL
API-MS-WIN-CORE-PRIVATEPROFILE-L1-1-1.DLL
API-MS-WIN-SERVICE-PRIVATE-L1-1-1.DLL
EDIT2
After adding these DLL's (had to download them from here) and seing I had to change the name of one of the DLL's I downloaded from this site, I now get the new error
This application failed to start because it could not find or load the
Qt platform plugin "windows".
Available platform plugins are: minimal, offscreen
And not the following runtime error.
Since I had to go to external sources to get the Microsoft DLL's, doesn't this really points to something faulty with the Windows 8.1 DLL's?
EDIT3:
To clarify, in my \platforms I have
qminimal.dll
qmoffscreen.dll
qwindows.dll
whilst in my \plugins I copied the same DLL's.
All required steps are described on this page of the documentation. Check especially the "plugandpaint" example under "Creating the application package".
My guess is that you are missing the second one:
myapp.exe
platform/qwindows.dll
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
And yes, dependency management on Windows is a pain. It should be part of the OS, instead, it's not, and you have to take care of everything yourself.

Failed to load platform plugin "windows". Available platforms are : Error

I've created Qt project using Visual studio 2012 32 bit and Qt5 SDK with the help of Visual studio Qt addon. I'm using Windows 7 ultimate OS.
I have created QApplication GUI Project which basically uses the following libraries:
qtmain.lib
Qt5Core.lib
Qt5Gui.lib
Qt5Network.lib
Ws2_32.lib
Winhttp.lib
Winmm.lib
Qt5Widgets.lib
Qt5PlatformSupport.lib
imm32.lib
And I have succeed in building the application binary without any errors.
I’m trying to run this application on test machine windows 7 desktop having following dlls copied there:
icudt51.dll
icuin51.dll
icuuc51.dll
libEGL.dll
libGLESv2.dll
Qt5Core.dll
Qt5Network.dll
Qt5GUI.dll
Qt5Widgets.dll
qwindows.dll [copied from msvc2012\plugins\platform folder ]
I’m getting the error:
Failed to load platform plugin “windows”. Available Platform are : while trying to run the application.
What would i have missed? How to make it run on windows platform? Please Help me to troubleshoot this.
I've followed the links posted about this problem previously. but none of them are solved my problem. What configuration I am missing?
The platform plugin dlls would need to be put into the platforms subfolder and then it will work.
Yet another solution: Early in your main function or whatever, call QCoreApplication::addLibraryPath(). A simple example:
std::ifstream configurationStream("whateverNameYouWant.conf");
std::stringstream configurationText;
configurationText << configurationStream.rdbuf();
auto ct = configurationText.str();
if (!ct.empty())
QCoreApplication::addLibraryPath(QString::fromStdString(ct));
Here I load the path from a .conf file of my own invention, so that the path won't be hardcoded into my program. Since I invented this file, I control its format; in this case it contains nothing but the path. The actual path I'm using is C:/qt5/qtbase/plugins; that directory contains platforms/qwindows.dll and other such files. One may adjust the paths for one's own case according to where one's Qt files are installed.
I guess it is also supposed to be possible to use a standard qt.conf file, using a format specified by Qt, to automatically load some special paths (including this plugins path) without having to add special code to your own program for the purpose: http://doc.qt.io/qt-5/qt-conf.html ...But I haven't ever managed to get that to work, for whatever reason. Maybe I'm making some simple mistake, I dunno.
An other solution is to add arguments to the QApplication object (or to the starting application).
For instance, you want to load qwindow.dll from C:\test\platforms.dll, you can instanciate QApplication object with the following code :
int ac = 4;
static char * av[] = {"myappli.exe","C:\\\\path\\to\\myappli.exe","-platformpluginpath","C:\\\\test"};
m_qApp = new QApplication(ac, av);
Be careful, the QTCore dll can't be into the directory C:\test (loading dll conflict)
If you specify a working directory different than the one where your executable is located, no matter the plugins are there, it will fail.
So, in that case, copy your file with a post build event.
And in:
Configuration properties->Debugging->Command
specify the full path of the executable.
This was tested on VStudio 2008.

QBSDK Distribution for VB6 App

Ok, I went through great lengths but I finally got my integration to quickbooks working on my VB6 application. It works perfectly on my build machine. I actually installed the qbdsk11 on my build machine and worte and tested the code. The ONLY new reference in the project is the QBFC11.dll.
So, I added the QBFC11.dll to my innosetup, told it to do a regsvr on the dll, and hoped this was enough.
NOT.
First, during install, I get a failure to register the dll. Apparently, this DLL isnt meant to be registered?
But the .DLL was put in Windows System32, so I tried my program anyways...
NOPE. Doesnt work. I get a runtime 91, about an object variable not set. Which makes sense, if it cant create the object.
So, for grins, I moved a copy of the .DLL into the program folder, next to my executable.
Same thing. Runtime error 91.
So, i then grab the whole qbsdk11 installer and install it on this machine. I figure I can make it an additional download for people who want to use this extra functionality.
But no, even with the whole SDK installed, I still get the same runtime error.
I have not been able to find any CLEAR information on how to proceed. I'd prefer for this to be part of my base install. But apparently something still just isn't right.
What did I miss? How do I fix this? I don't even know what to try next.
If you're using QBFC11, you must install the QBFC11 redistributable components with your application. You can find instructions on how to do this in the QBSDK Programmer's Guide in the section titled Redistributing SDK Components With Your Application, subsection Using Installers and Merge Modules.
The most likely cause of the runtime error you're currently getting is the manipulation of the QBFC11.DLL that you did before you installed the SDK. I would start again with a clean OS image so that you can get the proper procedure down.

Qt4 Program Crashing Unless SDK Installed

I've written a Open Source program that I've released as GPL built using the Qt4 LGPL SDK. This program has the ability to search an optional Sqlite3 database for data.
Here is what is making me lose my mind. I compile the program on the development machine. When I try to run it, I can errors about missing DLLs. I copy those dlls into the same directory as the executable and it now works fine ( mingwm10.dll, libgcc_s_dw2-1.dll, QtCore4.dll, QtSql4.dll, QtGui4.dll ), including the database search.
Now, if I copy that folder with the executable and the DLLs to a new machine that has not had the SDK installed on it, it runs fine until I try to search. As soon as I hit the search button, I can the following error:
Title: Microsoft Visual C++ Runtime Library
Runtime Error!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I then download and install the SDK, doing nothing else, I can now run the program and search the sqlite3 file just fine!
What magic am I missing?
P.S. Both machines are freshly installed Windows XP systems.
You may have some libs or Qt plugins that are not deployed to the target machine. It most likely is the SQL driver plugin. Here's some info about it: http://doc.trolltech.com/latest/deployment-windows.html#qt-plugins
You'll need to copy the needed Qt plugins to a directory next to your executable. And add something like this in your main():
QApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/plugins");
(Edited link and added code)
I found the problem.
Stephen Chu was correct in that I was missing the sqlite driver. However, I can into more complications along the way.
The SDK comes with two sets of dlls. One set resides in $BASEDIR/bin and the other in $BASEDIR/qt/bin. The former contains the dlls used by Qt Creator, while the latter are the dlls that you want to ship with your executable.
I needed to take the sqlite plugin ( qsqlite4.dll ) and copy it to APP_DIR/sqlplugins. My problem was I was using the wrong qsqlite4.dll file.
A big thanks to everyone who contributed to this question.
For future reference, this issue was also discussed here: http://www.qtforum.org/article/34639/qt4-program-crashing-unless-sdk-installed.html

Resources