Suppose I have two libraries, A.dll and B.dll. The library A depends on B. I want to load A into my project.
My project is in C:/Project. If I keep both A.dll and B.dll in C:/Project, I can load A with:
QLibrary lib("A");
lib.load();
This works fine. load() will return false if B.dll isn't in C:/Project, though.
The problem is I want to keep both A.dll and B.dll in C:/Project/lib. But when I move both libs to that location and try to load:
QLibrary lib("C:/Project/lib/A");
lib.load();
It fails. But this works if I keep A.dll in C:/Project/lib and B.dll in C:/Project.
How can I keep both libs in C:/Project/liband have A.dll load successfully?
Edit: the error message I get is "Cannot load library C:/Project/lib/A . The specified module could not be found."
Try using SetDllDirectory, see http://msdn.microsoft.com/en-us/library/ms686203%28VS.85%29.aspx
You should add into your system environment the path to C:/Project/lib, or from the Projects tab into your QT Creator edit the Path variable(add the path to your libraries)
Related
I have a sample solution with a console and library project. Both reference the same nuget but a different version. The console project also has a reference to the library project. So the structure is like this:
- Solution
- ConsoleApp
- Project Reference: Library
- Nuget: NServiceBus.RabbitMQ (5.2.0)
- Library
- Nuget: NServiceBus.RabbitMQ (6.0.0)
You can find the solution here.
Since Nuget uses the nearest wins rule, the nuget package that gets resolved is version 5.2.0. This is what I want, so far so good. But when I run the application and run a method of the Library I get the following exception:
Could not load file or assembly 'NServiceBus.Transport.RabbitMQ, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
In .NET Framework I would solve this with an assembly redirect. But that isn't available in .Net Core. I always thought that .Net Core solves this automatically by using the deps.json file. There I see the following statement:
"Library/1.0.0": {
"dependencies": {
"NServiceBus.RabbitMQ": "5.2.0"
},
"runtime": {
"Library.dll": {}
}
}
But still at runtime he tries to resolve the 6.0.0 version. I'm using the latest .Dot Net 3.1.X SDK.
I'm I doing something wrong or does this seem like a bug?
For the record, this is a simple sample project. The actual situation where I need this is much more complex. I also do understand that doing this can cause runtime exceptions while running the application.
It appears to be by design.
A little bit of searching, I found this: https://github.com/dotnet/fsharp/issues/3408#issuecomment-319466999
The coreclr will load an assembly of the version or higher than the reference. If the assembly discovered is lower than the reference then it fails.
Also this: https://github.com/dotnet/sdk/issues/384#issuecomment-260457776
downgrading the assembly version isn't supported on .NET Core
So, to confirm, I spent much more time than I intended looking/searching through https://github.com/dotnet/runtime. Eventually I found the assembly version compatibility method: https://github.com/dotnet/runtime/blob/172059af6623d04fa0468ec286ab2c240409abe3/src/coreclr/binder/assemblybindercommon.cpp#L49-L53
It checks all the components of the version separately, but if we look at just one, we can see what it's doing:
if (!pFoundVersion->HasMajor() || pRequestedVersion->GetMajor() > pFoundVersion->GetMajor())
{
// - A specific requested version component does not match an unspecified value for the same component in
// the found version, regardless of lesser-order version components
// - Or, the requested version is greater than the found version
return false;
}
As the comment says, the loader will reject the assembly if the assembly's version is lower than the requested version. In your case, assuming that the assembly version matches the package version (which it doesn't have to), your library is requesting version 6.0.0, but the assembly loader/binder, found version 5.2.0 on disk, which is lower. Hence, it rejects that dll, keeps looking, but then can't find a suitable version of the assembly on the probing path and eventually throws the FileLoadException.
What's not clear to me is if this assembly compatibility is checked only on the default assembly loader, or even if you add your own event handler to AssemblyLoadContext.Default.Resolving. You could try adding your own handler and when it requests the assembly of the higher version, you return the lower version assembly anyway. It might be a way to work around the issue.
I have 2 QML Plugins: icL.Look and icL.Editor, the second depend by the first. If I exclude the dependency all are working OK. But I need it. So when I run the app I get the next error
qrc:/windows/start-window.qml:5 plugin cannot be loaded for module
"icL.Editor": unable to load library /path/libicLeditorPlugin.so:
(/path/libicLeditorPlugin.so: undefined symbol: _ZN3icL4look5Chars5clineE)
21:52:20: The program has unexpectedly finished.
icL.look.Chars.cline is a static field.
Do you have some idea?
I'm trying to add the automation libraries to my project in Flash Builder so we can automate our testing.
I've added this to the additional compiler settings:
-include-libraries+="${flexlib}/libs/automation/automation.swc","${flexlib}/libs/automation/automation_agent.swc","${flexlib}/libs/automatio n/automation_dmv.swc","${flexlib}/libs/automation/automation_spark.swc ","${flexlib}/libs/automation/automation_air.swc","${flexlib}/libs/aut omation/automation_airspark.swc","${flexlib}/libs/automation/qtp_air.swc"
and -locale nl_BE fr_BE
After compiling this I get 2 errors:
Unable to resolve resource bundle "automation_agent"
Unable to resolve resource bundle "qtp_air"
However, in my nl_BE and fr_BE folders under flex_sdk\frameworks\locale\ the automation_agent_rb.swc and qtp_air_rb.swc are present.
If I switch to en_US, it works fine.
Can somebody explain to me why Flash Builder can't find these resource bundles?
Try explicitly adding automation_agent_rb.swc and qtp_air_rb.swc to your library-path as well.
I have created a plugin for my application. If I don't use the GDAL library in my code, my application can use this plugin (QPlugin loads it) and it works fine. But if I use classes from the GDAL library QPluginLoader can't load it and the errorstring() method returns ../serverplugin.dll Can't find module.
There are two exported symbols qt_plugin_instance and qt_plugin_query_verification_data in the plugin DLL (I found them with Dependency walker). QPluginLoader uses the QLibrary class internally to interface with the C symbols exported to the DLL. If I don't use GDAL I have only two exported symbols in all plugins at the beginning. When I use GDAL these two symbols are moved at the end of a big list of exported symbols. Maybe these two exported symbols should be at the beginning.
What am I doing wrong?
I had the same problem with QPluginLoader. In few words how I solved it: I create plugin library, let's say lib1.dll which use some stuff from lib2.dll. In my application I try to load lib1 via QPluginLoader.
QPluginLoader loader( adaptersDir.absoluteFilePath(fileName) );
AdapterInterface* adapterIface = qobject_cast<AdapterInterface*>(loader.instance());
In this case loader.instance() returns 0. Solution was to copy lib2.dll into application folder because an application use it for proper load plugin lib1.
QT_BEGIN_NAMESPACE
#define Plugin_iid "Plugin"
Q_DECLARE_INTERFACE(PluginInterface,Plugin_iid)
QT_END_NAMESPACE
Q_PLUGIN_METADATA(IID "PluginInterface" FILE "Plugin.json")
Q_INTERFACES(PluginInterface)
I've made a runtime shared library for my project, let's call it ResourceLibrary. It contains all of the embedded assets for my project (images, sounds, movie clips) and it's used as a singleton in a lot of other bits of code.
I am compiling it using this batch (Windows unfortunately):
SET normalstuff=--namespace+=http://ns.adobe.com/mxml/2009,${flexlib}/mxml-2009-manifest.xml --namespace+=http://www.adobe.com/2006/mxml,${flexlib}/mxml-manifest.xml --namespace+=library://ns.adobe.com/flex/spark,${flexlib}/spark-manifest.xml -external-library-path lib -external-library-path+=${flexlib}/libs -external-library-path+=${flexlib}/libs/player/10.0
call compc -source-path src/ -output lib-ext/resources.swc -include-namespaces+=http://MYPROJECT -namespace+=http://MYPROJECT,confs/ResourceLibrary-manifest.xml %normalstuff% -library-path+=data/characters -library-path+=data/menus -library-path+=data/icons/relationships -include-lookup-only=true
That makes my resources.swc file, which, when I include this swc in my library and have -static-link-runtime-shared-libraries=true. But I want to not embed my runtime shared libraries in my main swf (cuts down the file size from 10mb to ~3mb), so static-link-runtime-shared-libraries must be false.
When I run my code, however, I get this error:
[Starting debug session with FDB]
[Fault] exception, information=VerifyError: Error #1014: Class mx.core::BitmapAsset could not be found.
I've been raking my brain over this probably super simple solution, but everywhere I look the answer everyone else gets is "static-link-runtime-shared-libraries to true".
Anyone have any clues/ideas on where to start?
I figured this out but forgot to post here.
What you have to do is tell it where the swf to be used will be located, and what classes will be in it (the swc arg)
-runtime-shared-library-path=lib/MyLibrary.swc,MyLibrary.swf
I then extract the swc (using 7zip, but any works) and re-name the extracted swf to "MyLibrary.swf" and move it into the same directory as my main program.
If you're using a SDK that doesn't match the version of Flash Builder you're using, you may need to manually link to that SDK in the project properties.
You do know that creating a swc is not an RSL, right? swc = compile time library. swf = runtime library (or swz if it's Adobe signed libs).
http://livedocs.adobe.com/flex/3/html/help.html?content=rsl_01.html#168690
http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_14.html