VC++: #import directive: how to specify a library version? - visual-c++

According to MSDN, there is version attribute but if you specify a wrong version number VC still compiles the code. For example:
// MSO.DLL (Microsoft Office, Object Library)
// Office 10.0 => version(2.2)
// Office 11.0 => version(2.3)
// Office 12.0 => version(2.4)
#import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" version(123.456) //< wrong version.
How to force the compiler to fail on such code? I would like to use only specific version of type-library.

You can't. The rules are explained in LoadRegTypeLib:
LoadRegTypeLib compares the requested version numbers against those
found in the system registry, and takes one of the following actions:
If one of the registered libraries exactly matches both the
requested major and minor version numbers, then that type library is
loaded.
If one or more registered type libraries exactly match the
requested major version number, and has a greater minor version number
than that requested, the one with the greatest minor version number is
loaded.
If none of the registered type libraries exactly match the
requested major version number (or if none of those that do exactly
match the major version number also have a minor version number
greater than or equal to the requested minor version number), then
LoadRegTypeLib returns an error.
Your case matches the 2nd bullet, not the 3rd. Microsoft does spend a lot of effort on making these type libraries backward compatible. Not taking advantage of it is easy to do. Build your project on a machine with the right type library. Copy the generated .tlh and .tli files to your project directory and check them in. Replace the #import with #includes for those files.

Related

How to replace a native dynamic library file permanently and appropriately

I try to develop a thirdparty unixODBC driver, it is a secondary development based on the original file libodbc.so.2.0.0.
so I want to rename 'libodbc.so.2.0.0' to 'libodbc.so.2.0.0_renamed'. And soft link my dynamic library file to libodbc.so.2.0.0.
But I found an issue bothering me, when I rename native file and run 'sudo ldconfig', the file named 'libodbc.so.2' automatically linked to the renamed file 'libodbc.so.2.0.0_renamed', as below:
I could not understand that:
why it occurs;
how to appropriately replace the library.
I don't have enough ackownledge about linux, so that I failed to get any keyword to search and deal with it.
Could you help me, thank you very much!
Shared objects under GNU/Linux follow a specific version naming scheme, which is known by the loader (and OS component, actually part of libc framework) to determine if a newer library is retro-compatible with some older version to which a binary was originally linked against. By adding the renamed suffix, you are violating the convention and the dynamic linking system is getting confused. You should renamed as suggested by #Bodo above.
In addition, perhaps rather than using rename, you might consider using the very versioning scheme. From GNU Build System (aka Autotools) manual, the version cheme is like it follows:
Versioning: CURRENT:REVISION:AGE
CURRENT The latest interface implemented.
REVISION The implementation number of CURRENT (read: number of bugs fixed...)
AGE The number of interfaces implemented, minus one.
The library supports all interfaces between CURRENT − AGE and CURRENT.
If you have
not changed the interface (bug fixes) CURRENT : REVISION+1 : AGE
augmented the interface (new functions) CURRENT+1 : 0 : AGE+1
broken old interface (e.g. removed functions) CURRENT+1 : 0 : 0
Therefore a possible history of your lib might be:
1:0:0 start
1:1:0 bug fix
1:2:0 bug fix
2:0:1 new function
2:1:1 bug fix
2:2:1 bug fix
3:0:0 broke api
3:1:0 bug fix
4:1:1 bug fix
5:0:0 broke api
You might, for instance, call the older and newer versions of libodbc.so.x.y.z, according to your needs. Just an idea.

Azure Emulator loading incorrect libraries

The situation is as follows:
Let's say I have a project with 2 nuget library references - lib A and B:
A is at version 1.5
but B references an older version of A, e.g. 1.4
In VS, everything can compile and run properly (I guess because A 1.5 implements all the functionality that 1.4 required).
But running in the Azure emulator resulted in an immediate TypeLoadException, presumably because the older version of A was loaded (I think its because B was loaded first, and its dependency was A 1.4), thus the types and methods (e.g. MyObject) added in A 1.5 and used by my project are not recognized.
Exactly what I get is:
"Could not load type 'MyObject' from assembly 'A, Version=1.4, Culture=neutral, PublicKeyToken=null'."
I've substituted the real names and version numbers with A and 1.4 of course :)
I know that one solution would be to update B to use A 1.5, but is there any other way to fix this? In case there are other libs B, C, D, E... that use A 1.4, I would have update the reference to A in all of them...
Thanks for any help
Either upgrade your projects to use the latest NuGet package or try adding a binding redirect to your app.config to map assembly references to the higher version.

Why /lib/ld-linux.so.2 soname version bumps are so rare?

As far as I understand, "2" in "/lib/ld-linux.so.2" changes very rarely. There are old programs that can't work with new library and new programs that can't work with the old library. But they both refer to /lib/ld-linux.so.2, preventing installing both libraries.
BTW what are that version 'GLIBC_2.17' not found things? Why version is not in soname, but somewhere else?
Whenever a library is changed in a way that old programs do not work with the new version of the library this number is chaned. If old programs will still work with the newer library (and programs needing the new version will not cause a crash with the old library) there is no need to change the number because you can simply install the latest version of the library.
As far as I understand the "2" (it was "1" ten years ago) should not change any longer. The reason is simple:
The first version of "ld-linux.so.2" was written in a way that any version of "ld-linux.so.2" should work with any program using this file - maybe printing an error message when an older version of "ld-linux.so.2" is used.
This means: It is never necessary to install two different "ld-linux.so.2" files but it is enough to install the latest version of this file. You should not simply overwrite this file because it comes as a bundle with other files (e.g. "libc.so.6") that must have the same version.
In the "2" version of the loader .so files may contain a table of version numbers supported. So "libc.so.6", version GLIBC_2.16, may contain the information that "GLIBC_2.15" is also supported by this version of the library. (New versions should be backward compatible so this should be the case.)
Programs may contain a list of versions required (for example: a program requires libc.so.6 version "GLIBC_2.17"). The loader (ld-linux.so.2) checks if the library supports the version that is required by the program and refuses starting the program if not. In this case the error message form your question is printed by the loader.

Installshield 2011 - Problem Upgrading existing software with Version format 2009.727.1365

Using Installshield 2011, we're creating a major upgrade and having problems upgrading software with this Product Version format - 2009.727.1365. We keep getting the standard 'Installed software is newer than product to be installed' message. With IS 2011, the major version has to be less than 255, from what I can gather, and I think the old format we're using is breaking the check for upgrading.
I've created a test IS project upgrading from 1.00.0000 to 2.00.0000 with no issues, so I'm thinking the issue has to be related to the format of the product version already installed.
Is there a way to use InstallScript or something to compare our old format with the new one and then do an override?
Any help would be greatly appreciated. Thanks in advance!!
**I ended up using Christopher's reply in the link he provided below (Exceeding Version Limits). This seemed to handle the uninstallation of the existing product very well. Thanks again Guys!
It sounds as if you'll need to remove or modify the ISPreventDowngrade major-upgrade item, which is what detects and prevents this kind of version downgrade (and which is usually what one wants).
(Posted follow-up to question here, too: http://community.flexerasoftware.com/showthread.php?t=195076.)
Your ProductVersion property is invalid. The SDK says:
The value of the ProductVersion property is the version of the product in string format. This property is REQUIRED.
The format of the string is as follows:
major.minor.build
The first field is the major version and has a maximum value of 255. The second field is the minor version and has a maximum value of 255. The third field is called the build version or the update version and has a maximum value of 65,535.
I also recommend reading Exceeding Version Limits.
There are hacks to work around this if you understand how FindRelatedProducts and RemoveExistingProducts works.
Even though this is an older I'd like to add my two cents.
I am creating an Installshield 2012 Spring project and I had the same issue.
Our previous installers had a Product Version in the format 2005.xx.xxxx. Obviously this 2005 was an issue.
Instead of setting the ISACTIONPROP1 property to any value (as mentioned in http://community.flexerasoftware.com/showthread.php?195076-Old-Product-version-in-2009-727-1365-format).
I added a major upgrade item with the following values:
Product code of the old installers: xxx (enter yours here)
Minimum version: 2005.001.0001
Maximum version: 2005.255.65535
Version Range Inclusive (might be overkill)
With this, the system does allow the 2005.xxx.xxxx format here. It detected and removed the previous installation. For our newer installations we will use our "normal" versions:
5.008.0001
5.009.0001
...

difference between .so.0 and .so.0.0.0 files

Im using a market data source implementation that contains .so.0 files. However these are 'soft links' to actual .so.0.0.0 files. Why is this done?
When I try to copy these .so.0 links, it ends up copying an exact replica of the .so.0.0.0 file but with a .so.0 prefix.
Added comment:
so I have a libfoo.so file, and it is being accessed by java through jni. This libfoo.so file is actually a soft link that points to libfoo.so.0.0.0 What happens if I don't have libfoo.so. How does java/or any other compiled code, figure out that libfoo.so.0.0.0 if the shared object to use?
This is so programs can bind to either any version of libfoo that has the same interface (I want the latest updates to libfoo), or bind to a specific version (I want stability and only the exact version I tested against).
The .0 and .0.0.0 files exist so that versioning can happen:
foo.0 represents the .0 version of a library. All .0 versions of the library will use the same interface, but there may be different implementations. (Hopefully, the later implementations will have fewer bugs than the earlier ones.)
foo.0.0.0 represents a specific implementation of the .0 version.
It's not useful, now, to have the soft-link. But here's what could happen:
The programmer of foo finds a bug in his library. He releases foo.0.0.1. And foo.0 now links to foo.0.0.1. Then two things happen:
All files that link to foo.0 will automatically update to foo.0.0.1.
All files that link to foo.0.0.0 will continue to use the old foo.0.0.0

Resources