I am writing a C++ library that uses boost.
In this library I want to include information about the boost version that was used to compile the binary version of my library.
I can use the macro BOOST_VERSION
and this is fine.
I also wanted to determine which is the runtime version of boost so I could compare with the boost version that was used to compile my library. Obviously I cannot use the macro because it will give me the hard coded version at compile time, not at runtime.
What I needed is a function in boost (like boost::get_version()
). Is there a way to do this in boost?
You can check version. hpp inside Boost include dir (normally /usr/include/boost , you can use locate /boost/version. hpp or similar to get that) for BOOST_VERSION or BOOST_LIB_VERSION .
Boost is a set of libraries for the C++ programming language that provides support for tasks and structures such as linear algebra, pseudorandom number generation, multithreading, image processing, regular expressions, and unit testing. It contains 164 individual libraries (as of version 1.76).
The headers should be in /usr/local/include/boost and the libs should be in /usr/local/lib.
You can use the macro to create some code as follows:
std::cout << "Using Boost "
<< BOOST_VERSION / 100000 << "." // maj. version
<< BOOST_VERSION / 100 % 1000 << "." // min. version
<< BOOST_VERSION % 100 // patch version
<< std::endl;
This works on boost 1.51.x and upwards. Not sure if this is what you are looking for though, I will keep going and see if there is a way to get it from the currently loaded dll in a more elegant way.
To find run-time versions:
After looking at the Boost system, it seems that the simplest way you could do what you are looking for would be to have platform dependant code which is utilised at compiletime to make the different versions of executable.
You will need to query the DLL for its version using GetFileVersionInfoEx API or GetFileVersionInfo API, you also need to take into account if the OS is 32 bit or 64 bit, so here is some code which may be of use:
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS IsWow64ProcessFunc;
BOOL is64BitOS()
{
BOOL retval= FALSE;
// need to check if the OS is 64 bit, and we cant therefore indiscrimately call the 64 bit function for this, so we use the following:
IsWow64ProcessFunc= (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if(IsWow64ProcessFunc != NULL)
{
if (!IsWow64ProcessFunc(GetCurrentProcess(),&bIsWow64))
{
// your error handling code in here
}
}
return retval;
}
Then we can utilise a straight-forward bit of code to get the version of the DLL:
void myWindowsDLLVersionChecker()
{
DWORD versionHandle = NULL;
UINT size = 0;
LPBYTE buffer = NULL;
DWORD versionSize = GetFileVersionInfoSize( szVersionFile, &versionHandle);
if (verSize != NULL)
{
LPSTR versionData = new char[versionSize];
if (GetFileVersionInfo( szVersionFile, versionHandle, versionSize, versionData))
{
if (VerQueryValue(versionData,"\\",(VOID FAR* FAR*)&buffer,&size))
{
if (size)
{
VS_FIXEDFILEINFO *versionInfo = (VS_FIXEDFILEINFO *)buffer;
if (versionInfo->dwSignature == 0xFEEF04BD) // value from http://msdn.microsoft.com/en-us/library/windows/desktop/ms646997(v=vs.85).aspx
{
if(is64BitOS()) // if it is true then its a 64 bit Windows OS
{
major = (versionInfo->dwProductVersionMS >> 16) & 0xff;
minor = (versionInfo->dwProductVersionMS >> 0) & 0xff;
revision = (versionInfo->dwProductVersionLS >> 16) & 0xff;
build = (versionInfo->dwProductVersionLS >> 0) & 0xff;
}
else // 32 bit Windows OS
{
major = HIWORD(versionInfo->dwProductVersionMS);
minor = LOWORD(versionInfo->dwProductVersionMS);
revision = HIWORD(versionInfo->dwProductVersionLS);
build = LOWORD(versionInfo->dwProductVersionLS);
}
}
}
}
}
delete[] versionData;
}
}
Horribly cant remember the code for that at present, however here is a partial solution from memory (I don't have a Linux machine to hand at the moment, will check this in more detail later, but should work with only minor modifications at most).
void myLinuxDLLVersionChecker()
{
// call readelf as an external proces son libboost_system.so,
// and use the information returned to extract the version from.
// or use something like
setenv("LD_TRACE_LOADED_OBJECTS", "1", 1);
FILE *ldd = popen("/lib/libboost_system.so");
// information from http://linux.die.net/man/8/ld.so
// the above pretty much replicates ldd's output, so you can pick out the version
}
To make the same thing happen in multiple OSes you would probably have to use something like:
#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
void detectBoostDllVersion() // does not have to be void, can be whatever you need
{
myLinuxDLLVersionChecker();
}
#elif defined(_WIN32) || defined(WIN32) /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
void detectBoostDllVersion() // has to match the same return type as the previous version
{
myWindowsDLLVersionChecker();
}
#endif
Now dependant upon which OS this is compiled for, the right function will be pointed at by the detectBoostDLLVersion()
function :)
There is no such feature in boost and I think you can only scan binary file for this thing (ldd
in linux for example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With