I had a program written using Qt's shared library version (5.2.0) and it displayed fonts okay (presumably filling it's Database from /usr/share/fonts). (Not sure whether the Designer text is from the same Database as the programmed font handling.) But then I recompiled it under the open source static version (5.2.0), and the fonts went ugly.
I disrupted the path to the installed Qt (since the whole idea of the static version is to be independent of development directories) and sure enough it complained of not being able to access any fonts. So I concluded Qt changed their static version to no longer input /usr/share/fonts. A little research on the internet told me they instead look under ...somedir/lib/fonts.
With a little more research I found I could use env var QT_QPA_FONTDIR to set the directory of search (though I suspect it might have been reduced to a one-level search, not recursive). Not wanting to have to write a script to wrap the program and set the environment variable before calling it, I proceeded to use a putenv() in the program. I chose a place that I thought would set the variable before Qt read the environment, and since global contructors are called before main() and certainly before QApplication is instantiated, I put it in a constructor.
But, guess what, they seem to read the environment before my constructor set the QT_QPA_FONTDIR=/usr/share/fonts.
So please help!!!! How do I make MY constructor get executed first?
Some compilers offer pragmas that attempt to help you do such things, but the simple truth is that C++ offers no guarantees of the order of global construction between modules. There isn't even a guarantee that one object dependent on another in another module will be initialized second. Globals are a minefield in this respect.
If you need a portable solution, there really isn't one.
If you can guarantee your compiler will always be the same flavor, then you can use hacks like pragmas, attributes, or link order to work around the problem. For instance, gcc offers a variable attribute called init_priority, though I'm not sure you can make your priority higher than the default.
Really, it would be better to solve the problem another way.
Thank you Aiken Drum. The link order worked. I created the smallest .cpp that made a constructor to be instantiated globally calling the putenv() to set up my environment. I put it first in the .pro file, and checked that the makefile it created had it first in the link line. And, hey presto!! the Qt program now gets the font Database from the right place. Thank you so much. It's the link order that sets the constructor order (at least with GCC).
Related
Qt + C++ + C gurus, I could some advice:
I started writing a Qt6 GUI C++ app that includes some extern C code. Much to my surprise, upon launch the ui->setupUi(this) call immediately segfaulted and I found myself inside of one of the extern C functions that was imported! This is literally at the first line of my MainWindow constructor - with no calls to any of the C code even added yet.
The C function where the segfault dumped me was named "crc32". I temporarily renamed it (and all calls to it) to test my theory and sure enough the program started correctly afterwards. So... Qt appears to invoke "crc32" when doing things like adding QMenu items... due to some name collision.
I'm puzzled how to fix it. I don't want to change the C code because it's actually a git submodule for a project I do not want to maintain a fork of forever. Since it's Qt calling it from the C++ side, I can't exactly specify the namespace on the call either.
Weird sidenote: When I was doing testing this morning with Qt5 (instead of 6), I was not running into this issue. The crc32 name collision may be specific to Qt6.
Looks like you are on Linux (or similar) and encountering a violation of the One Definition Rule. When the shared lib loader tries to load symbols from a shared lib, it will first check to see if it already has one with that name loaded. If so, it skips it. Thus, if you try to load two symbols with an identical name, you'll only get one of them, and then problems can ensue.
Possible options:
Hide symbols you don't need in the library. For this, consider using GCC's visibility controls.
Separate the symbols into different executables and share data with some interprocess communication like shared mem or a socket.
Use dlopen() on one of the libs along with the RTLD_LOCAL flag so it does not override the symbol.
Add a namespace to the project (or use its build options to control that, if available -- like Boost does). Yes, this violates your wish not to modify it, but it could be done with a patch or similar that does not modify the original checkout if you switched to using a package manager like Conan instead of a git submod.
crc32 is a symbol from zlib. Qt does use either the system zlib, or a built-in version of it. If it uses the built-in version, symbols are prefixed with z_ (so z_crc32) to avoid exactly such a clash.
So, if you want to use crc32, you have the options to configure Qt to either not use zlib at all (-no-zlib), or use the built-in version (-qt-zlib).
So I watched this video months back where Epic showcased their new Unreal Engine 4 developer features. Sorry I could not find the video but I'll try my best to explain.
The one feature that got my attention was the C++ "on the fly" modification and compilation. The guy showed how he was playing the game in editor and modified some variables in the code, saved it and the changes were immediately mirrored in game.
So I've been wondering... How does one achieve this? Currently I can think of two possible ways: either a hoax and it was only "c style"-scripting language not C++ itself OR it's shared library (read: DLL) magic.
Here's something I whipped up to try myself(simplified):
for(;;)
{
Move DLL from build directory to execution directory
Link to DLL using LoadLibrary() / dlopen() and fetch a pointer to function "foo()" from it
for(;;)
{
Call the function "foo()" found in the dll
Check the source of the dll for changes
If it has changed, attempt to compile
On succesfull compile, break
}
Unload DLL with FreeLibrary() / dlclose()
}
Now that seems to work but I can't help but wonder what other methods are there?
And how would this kind of approach compare versus using a scripting language?
edit: https://www.youtube.com/watch?v=MOvfn1p92_8&t=10m0s
Yes, "hot code modification" it's definitely a capability that many IDEs/debuggers can have to one extent or another. Here's a good article:
http://www.technochakra.com/debugging-modifying-code-at-runtime/
Here's the man page for MSVS "Edit and Continue":
http://msdn.microsoft.com/en-us/library/esaeyddf%28v=vs.80%29.aspx
Epic's Hot Reload works by having the game code compiled and loaded as a dll/.so, and this is then dynamically loaded by the engine. Runtime reloading is then simply re-compiling the library and reloading, with state stored and restored if needed.
There are alternatives. You could take a look at Runtime Compiled C++ (or see RCC++ blog and videos), or perhaps try one of the other alternatives I've listed on the wiki.
As the author of Runtime Compiled C++ I think it has some advantages - it's far faster to recompile since it only compiles the code you need, and the starting point can be a single exe, so you don't need to configure a seperate project for a dll. However it does require some learning and a bit of extra code to get this to work.
Neither C nor C++ require ahead-of-time compilation, although the usual target environments (operating systems, embedded systems, high-performance number crunching) often benefit greatly from AOT.
It's completely possible to have a C++ script interpreter. As long as it adheres to the behavior in the Standard, it IS C++, and not a "hoax" as you suggest.
Replacement of a shared library is also possible, although to make it work well you'll need a mechanism for serializing all state and reloading it under the new version.
When you are setting up a project to compile in C++, be it VS or make, what is the best practice for setting up environment variables which are used in include paths for third party libraries? Do you include the version number in the variable? i.e.
THIRD_PARTY_LIB_3_1_1=c:\libraries\thirdparty\3.1.1
and then have $(THIRD_PARTY_LIB_3_1_1)\include in your include path
or
THIRD_PARTY_LIB=c:\libraries\thirdparty\3.1.1
and then have $(THIRD_PARTY_LIB)\include in your include path
The benefit of having the version number, is that you know what version you are supposed to be pointing to, the down side is that when you change versions, you have to update all of your project/make files.
The main problem I see in not having version numbers in the environment variable is that it is not explicit, and if you have two projects which use different versions, it becomes a maintenance nightmare and reproducing a build is nearly impossible.
It depends.
You should think about it in terms of how the build system would use that information to change its behavior. It won't act any differently whether you name it one or the other, then its just making more work (and possibly confusion) for yourself.
If a single build needs to include multiple versions of the same THIRD_PARTY_LIBRARY, then you would have to differentiate. Otherwise, when your project specific code specifies the path, that should be clear enough.
The benefit of having the version number, is that you know what
version you are supposed to be pointing to, the down side is that when
you change versions, you have to update all of your project/make
files.
If someone changed the path and not the variable name, would the path or the variable name be correct? It is kind of a silly thought, isn't it? When someone else doesn't change the variable name and you are the one trying to figure out why something is breaking, you'll regret that too.
The main problem I see in not having version numbers in the
environment variable is that it is not explicit, and if you have two
projects which use different versions, it becomes a maintenance
nightmare and reproducing a build is nearly impossible.
Build files and 3rd party libraries should be in source control. Your build system should document all of these things when making release builds. Usually you want your build system to be able to do a full checkout of the code base to ensure the build is correct. As a side effect of this, it should also know the revision numbers.
My experience is that environment variables are problematic to rely on, and increasingly so the more specific they are. Many times you need them, so I can't and won't tell you that it's wrong to use them. You can only have one top level source path environment variable though. If your build system can use paths based off that, that is only a single place it will fail. If you have one for every single library, you increase the points of failure.
I've been using dynamic libraries and GetProcAddress stuff for quite some time, but it always seems tedious, intellisense hostile, and ugly way to do things.
Does anyone know a clean way to import new features while staying compatible with older OSes.
Say I want to use a XML library which is a part of Vista. I call LoadLibraryW and then I can use the functions if HANDLE is non-null.
But I really don't want to go the #typedef (void*)(PFNFOOOBAR)(int, int, int) and PFNFOOOBAR foo = reinterpret_cast<PFNFOOOBAR>(GetProcAddress(GetModuleHandle(), "somecoolfunction"));, all that times 50, way.
Is there a non-hackish solution with which I could avoid this mess?
I was thinking of adding coolxml.lib in project settings, then including coolxml.dll in delayload dll list, and, maybe, copying the few function signatures I will use in the needed file. Then checking the LoadLibraryW return with non null, and if it's non-null then branching to Vista branch like in a regular program flow.
But I'm not sure if LoadLibrary and delay-load can work together and if some branch prediction will not mess things up in some cases.
Also, not sure if this approach will work, and if it wont cause problems after upgrading to the next SDK.
IMO, LoadLibrary and GetProcAddress are the best way to do it.
(Make some wrapper objects which take care of that for you, so you don't pollute your main code with that logic and ugliness.)
DelayLoad brings with it security problems (see this OldNewThing post) (edit: though not if you ensure you never call those APIs on older versions of windows).
DelayLoad also makes it too easy to accidentally depend on an API which won't be available on all targets. Yes, you can use tools to check which APIs you call at runtime but it's better to deal with these things at compile time, IMO, and those tools can only check the code you actually exercise when running under them.
Also, avoid compiling some parts of your code with different Windows header versions, unless you are very careful to segregate code and the objects that are passed to/from it.
It's not absolutely wrong -- and it's completely normal with things like plug-in DLLs where two entirely different teams probably worked on the two modules without knowing what SDK version each other targeted -- but it can lead to difficult problems if you aren't careful, so it's best avoided in general.
If you mix header versions you can get very strange errors. For example, we had a static object which contained an OS structure which changed size in Vista. Most of our project was compiled for XP, but we added a new .cpp file whose name happened to start with A and which was set to use the Vista headers. That new file then (arbitrarily) became the one which triggered the static object to be allocated, using the Vista structure sizes, but the actual code for that object was build using the XP structures. The constructor thought the object's members were in different places to the code which allocated the object. Strange things resulted!
Once we got to the bottom of that we banned the practise entirely; everything in our project uses the XP headers and if we need anything from the newer headers we manually copy it out, renaming the structures if needed.
It is very tedious to write all the typedef and GetProcAddress stuff, and to copy structures and defines out of headers (which seems wrong, but they're a binary interface so not going to change) (don't forget to check for #pragma pack stuff, too :(), but IMO that is the best way if you want the best compile-time notification of issues.
I'm sure others will disagree!
PS: Somewhere I've got a little template I made to make the GetProcAddress stuff slightly less tedious... Trying to find it; will update this when/if I do. Found it, but it wasn't actually that useful. In fact, none of my code even used it. :)
Yes, use delay loading. That leaves the ugliness to the compiler. Of course you'll still have to ensure that you're not calling a Vista function on XP.
Delay loading is the best way to avoid using LoadLibrary() and GetProcAddress() directly. Regarding the security issues mentioned, about the only thing you can do about that is use the delay load hooks to make sure (and optionally force) the desired DLL is being loaded during the dliNotePreLoadLibrary notification using the correct system path, and not relative to your app folder. Using the callbacks will also allow you to substitute your own fallback implementations in the dliFailLoadLib/dliFailGetProc notifications when the desired API function(s) are not available. That way, the rest of your code does not have to worry about platform differences (or very little).
Well, it's a kind of a web server.
I load .dll(.a) files and use them as program modules.
I recursively go through directories and put '_main' functors from these libraries into std::map under name, which is membered in special '.m' files.
The main directory has few directories for each host.
The problem is that I need to prevent usage of 'fopen' or any other filesystem functions working with directory outside of this host directory.
The only way I can see for that - write a warp for stdio.h (I mean, write s_stdio.h that has a filename check).
May be it could be a deamon, catching system calls and identifying something?
add
Well, and what about such kind of situation: I upload only souses and then compile it directly on my server after checking up? Well, that's the only way I found (having everything inside one address space still).
As C++ is low level language and the DLLs are compiled to machine code they can do anything. Even if you wrap the standard library functions the code can do the system calls directly, reimplementing the functionality you have wrapped.
Probably the only way to effectively sandbox such a DLL is some kind of virtualisation, so the code is not run directly but in a virtual machine.
The simpler solution is to use some higher level language for the loadable modules that should be sandboxed. Some high level languages are better at sandboxing (Lua, Java), other are not so good (e.g. AFAIK currently there is no official restricted environment implemented for Python).
If you are the one loading the module, you can perform a static analysis on the code to verify what APIs it calls, and refuse to link it if it doesn't check out (i.e. if it makes any kind of suspicious call at all).
Having said that, it's a lot of work to do this, and not very portable.