Does adding new static member in middle break binary compatibility of a C++ library? - static-members

I have a class which has many static members, but I have added new function in the middle of the header file.
Does this break binary compatibility? Clients need to be recompiled?
EDIT (1): Class has only static functions, no other functions and data members

Your class has no virtual functions, so your new middle function will not change the v-table. Other static members in the class (functions and global variables/data) are invoked by the appropriate symbol name on Linux, Unix or Mac and your change is backward compatible.
But it's a breaking change on Windows because all functions are invoked by the ordinal number instead of the name (unless you are using def files to define custom ordinals for functions).
Try the abi-cc tool to automatically check backward binary compatibility of your libraries.

Related

what is the use-case for dlmopen vs dlopen?

android has the concept of a linker namespace.
https://source.android.com/devices/architecture/vndk/linker-namespace
what exactly is a linker namespace in layman terms ?
when would we want to use dlmopen vs dlopen ?
what use case is dlmopen trying to solve that dlopen does not solve ?
The project I work on makes use of dlXXX API for loading shared libraries at runtime and we want to ensure that the symbols loaded from the shared library are completely isolated. Does dlmopen address this issue ?
from dlopen's man page :
The dlmopen() function differs from dlopen() primarily in that it ac‐
cepts an additional argument, lmid, that specifies the link-map list
(also referred to as a namespace) in which the shared object should be
loaded. (By comparison, dlopen() adds the dynamically loaded shared
object to the same namespace as the shared object from which the
dlopen() call is made.) The Lmid_t type is an opaque handle that
refers to a namespace.
The lmid argument is either the ID of an existing namespace (which can
be obtained using the dlinfo(3) RTLD_DI_LMID request) or one of the
following special values:
LM_ID_BASE
Load the shared object in the initial namespace (i.e., the ap‐
plication's namespace).
LM_ID_NEWLM
Create a new namespace and load the shared object in that name‐
space. The object must have been correctly linked to reference
all of the other shared objects that it requires, since the new
NOTES
dlmopen() and namespaces
A link-map list defines an isolated namespace for the resolution of
symbols by the dynamic linker. Within a namespace, dependent shared
objects are implicitly loaded according to the usual rules, and symbol
references are likewise resolved according to the usual rules, but such
resolution is confined to the definitions provided by the objects that
have been (explicitly and implicitly) loaded into the namespace.
The dlmopen() function permits object-load isolation—the ability to
load a shared object in a new namespace without exposing the rest of
the application to the symbols made available by the new object. Note
that the use of the RTLD_LOCAL flag is not sufficient for this purpose,
since it prevents a shared object's symbols from being available to any
other shared object. In some cases, we may want to make the symbols
provided by a dynamically loaded shared object available to (a subset
of) other shared objects without exposing those symbols to the entire
application. This can be achieved by using a separate namespace and
the RTLD_GLOBAL flag.
The dlmopen() function also can be used to provide better isolation
than the RTLD_LOCAL flag. In particular, shared objects loaded with
RTLD_LOCAL may be promoted to RTLD_GLOBAL if they are dependencies of
another shared object loaded with RTLD_GLOBAL. Thus, RTLD_LOCAL is in‐
sufficient to isolate a loaded shared object except in the (uncommon)
case where one has explicit control over all shared object dependen‐
cies.
Possible uses of dlmopen() are plugins where the author of the plugin-
loading framework can't trust the plugin authors and does not wish any
undefined symbols from the plugin framework to be resolved to plugin
symbols. Another use is to load the same object more than once. With‐
out the use of dlmopen(), this would require the creation of distinct
copies of the shared object file. Using dlmopen(), this can be
achieved by loading the same shared object file into different name‐
spaces.
The glibc implementation supports a maximum of 16 namespaces.
So yes, it can be used to isolate a loaded lib !

What is the basic difference between namespace , library and header files?

I was searching on the internet about the differences between namespace , header file and library but I am still confused that what is the basic difference between them , please give an answer in the context of programming language not any specific language like C or C++
Namespace
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
Library
In programming, a library is a collection of precompiled routines that a program can use. The routines, sometimes called modules, are stored in object format. Libraries are particularly useful for storing frequently used routines because you do not need to explicitly link them to every program that uses them.
Header Files
Header files contain definitions of Functions and Variables, which is imported or used into any C++ program by using the pre-processor #include statement. Header file have an extension ".h" which contains C++ function declaration and macro definition.
thanks
libraries contain predefined function definitions.
header files contain predefined function declaration means prototypes and also contains macros as well
When ever we install some compiler,we select the suitable version of compiler that our OS supports that means every compiler has some set of library functions where OS uses them for I/O.

Is there a conventional URI scheme for referencing code in a library?

Is there a standard or conventional URI scheme, like file: or http: for referencing objects in a dynamic library?
For example, if I were to represent a function in a library in the form of a unique string that can be used to look up that function (by whatever reflective means), how might I do that?
Specifically I'm developing this in Objective-C, and I assume different languages/platforms will have different representations (I know .NET has its own), but I'm curious about this in a more general sense.
No, the name of the symbol is derived from its name in your code. In windows you will assuming C or C++
HMODULE module=LoadLibrary( [path to your dll] );
//If the exported name is foo.
Function foo=(Function)GetProcAddress(module,"foo");
//Call function
foo();
FreeLibrary(module);
The exported name is compiler-dependent.
Acually such a naming scheme is quite useless. In C++ you can use something like (Note that you will have one FunctionCaller per function prototype)
FunctionCaller("your-dll.dll/foo")();
Where the constructor of FunctionCaller loads the library, calls foo and frees the library. However it is not good because:
it may happen that the return value points to a resource inside the library and then will become useless
loading libraries and perform function look-up is slow relative to calling the function found
What you do is
Load the library
Load functions that you will need
Use your functions
Free the library
Here you would need to refer to more than one symbol at a time which would require a more complex scheme than uri.
EDIT: If you want to the convenience of calling functions like that you could have a surviving FunctionCaller object that keeps all loaded modules and contains a map from function name to address for each loaded library.

Visual Studio - manage multiple files that are part of one Class - classes, modules

My VB project is large enough that it requires several files. It was originally developed as a Console App and I created each file as a MODULE. All modules could use subroutines, data structures and constants from other MODULES and everything worked fine. I needed to add basic windowing to the app and this required that the app be converted from a Console App to a Windows Forms App. The main window is Form1 which is not a MODULE but a CLASS. The problem is that some MODULE based functions cannot access subroutines, data and constants that are defined within the CLASS Form1 unless they are incorporated into the CLASS file and this makes the CLASS file very large. If I add a new Class file to the project, it also cannot interoperate with Class Form1 in the same way that multi-MODULE code interoperates.
How does one spread CLASS code across several files and still allow it to interoperate as if it were in a single file? Alternatively, how does one create several CLASS files that operate the way multiple MODULE files operate.
I am sure that there are all kinds of best practices that I am violating but the goal to to get some prototype software working and interfaced to some lab equipment.
Thank you in advance
Use a partial class (Partial keyword on the class declaration). Each partial "bit" of the class will be merged at compile time. All partial bits must be in the same project.
Modules are default shared and do not require initialization with the New keyword. When you made your console app a windows app, it became a class...You could change it to the same behavior as a module simply by making it a Public shared Class and making all properties and methods inside shared as well.
so while you can access your methods and properties in your modules without initialization, you would need to use the NEW method to initialize your Class methods.
To access the Class from the module you would simply have to use:
SomeModulemethod
dim x as new CLASS
CLASS.SOMEMETHOD
someModuleMethod End
You could also use Partial Classing to split up your Classes, but it is much better to decide if you really need a separate class for what you want to do.

How to update a C++ dll without needing to relink the exe with the lib file?

First off , I'm referring to a Windows environment and VC++ compiler.
What I want to be able to do is rebuild a Vc++ dll and maintain compatability with an exe that has already been linked to the lib without having to rebuild the exe or load the dll dynamically using LoadLibrary. In other words, is there a way to add classes and methods to a dll(but not remove any) and ensure the existing entrypoints remain the same?
If you export the functions from using a DEF file and manually specify the ordinals, you should be able to accomplish this.
Reference
http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx
It depends on how your EXE used the classes from the DLL. Adding new classes should not affect existing entrypoints. Aside from that, however, any the following will affect object size and/or layout, and as such will be a client-breaking change (note that this is technically VC-specific, but most of these apply to any sane implementation):
Removing fields (even private) from classes
Adding new fields (even private) to classes
Adding new base classes to existing classes
Removing base classes from existing classes
Adding new virtual method before an existing virtual method (adding new virtual methods after existing ones is okay, except for the case described in next point)
Adding a new virtual method in a class that is used as base class by another class in the same DLL which also has virtual methods
Changing type of existing fields
Changing signature of existing methods
Making a virtual method non-virtual, and vice versa
As long as you don't add any exported symbols, the ordinals won't change. If you add exported symbols through the standard dllexport mechanism, then that's going to be difficult to control. If you use the old style .xpf symbol file you might be able to control the ordering of the symbols in the lib (although I don't know this for sure - it might still reorder them however it likes), but it's tricky to do C++ symbols this way.
I think that ordinals are rarely used to resolve DLL imports anymore - I think that you have to use .def files to get the linker to use them. So as long as you don't change names or signatures of the exported functions, the .exe should work just fine.