R
Roger Irwin
List Management Account wrote:
> Out of curiosity, what is the best way to deal with shared libraries?
> Are there any systems that do it exceptionally well?
snip
> The Don Box book, "Essential COM" goes into great detail about
> the problems with shared libraries and how COM is supposed to
> correct these problems. The idea is to support an immutable
> interface so that you can update your private code with screwing up
> all of the clients that were compiled against an older version. Each
> class is given a globally unique identifier (GUID) and the DLL is
> registered in the registry. It's pretty interesting the thought
> processes that led to the development of COM
snip
> How does CORBA handle these issues?
Do not be blinded by science. It is an old problem, and there are NO new solutions, just re-hyped old ones.
The first great manifestation of 'shared' code was the Rom BIOS code we had on early desktop machines. True, the C64 did not exactly run many
apps simultaneously, but by the time we got the infamous system calls on the MAC then we had code shared by many apps, but of course it could not
change because it was in ROM, which was a bit of a pain.
That said, a program needed only to check the ROM version and it new what to expect, and could put different wrappers around calls dpending on the
ROM version.
Of course that put the work on all the calling apps, how much nicer if the called library recognized what the caller was looking for, the old version or the new version, and served accordingly.
I do not know who was the first to define or deploy such concepts (but likely to be some IBM fellow in the late 60's, certinaly long before most people realised a problem existed), BUT, I do now a system that manifests the techniques very well.
SUN RPC's are an IPC method by which a program on one machine can call a function than is part of a different application on a different machine,
and they were introduced about 15 years ago, long before people started talking about COM objects, let alone DCOM. You may never have heard of them, but they are very widely deployed in the telecomms industry, all the control and supervision of the elements of the telephone network (cellular phones, internet POP's.......) is carried out by RPC's (Gradually being replaced by CORBA).
With RPC, a call to a method on a remote machine is governed by a definition file 'gen.x'. This file contains C like function definitions,
but includes tags for identifing the function call and giving it version numbers. The server may register different version of the same call with the RPC mechanism, such that when the client machine establishes a connection with the server, the server knows which version of the function it will expose to the client. Sound familiar? In the case of RPC's this mechanism works very well, and the same concept may be found in re-hashed form, complete with volumous helpings of marketing hype.
But in essence there is no efficient way to make a call to a method if the interface has been mutated, so the basic underlying technique is to
identify the version of the interface such that the corresponding method may be called.
Now I am no expert on the internals of C++ runtime binding, but it would seem to me that I could achieve the smae goal using a standard C++
compiler with no extensions.
Consder the following:
int foo:oIt(){
return baa;
}
If I had typedeffed my int with a version number, I could later add different versions to the same library:
#typedef int fooBack
#typedef int fooBack2
fooBack foo:oIt(){
return A;
}
fooBack2 foo:oIt(){
return B;
}
This way a modified DoIt function could be included in a library, and the oveloading mechanisms would determine what gets called, depending on header file with which the program was compiled.
The point I am trying to make is that we have a simple problem that has simple solutions, that can be implementated without a whole load of new
'gunge'.
Now, a tail observation. On Linux, shared libs have filename conventions which identify the major and minor versions, e.g. libcSO.5.1.3, when an app calls the library it knows which version of the library it was compiled against, so it invokes that. Obviously nobody wants a copy of
every single release on their system, so minor versions are enetered as symbolic links to the latest greatest bug fix release.
Of course the minor numbers represent bug-fixes, the API should be the same fpr a given major number. But in reality bug-fix releases can break
because somebody who has developed against a bug-fixed version may have encountered the bug and done a workaround that causes failure on the
bugfixed verdion, in essence I now need the old and new versions n the machine.
So, in Linux I simply replace the symbiolic link with a rea version of the buffy file, how do I do something similar on 'other' platforms?
Obviously one does not want to have every minor release
> Out of curiosity, what is the best way to deal with shared libraries?
> Are there any systems that do it exceptionally well?
snip
> The Don Box book, "Essential COM" goes into great detail about
> the problems with shared libraries and how COM is supposed to
> correct these problems. The idea is to support an immutable
> interface so that you can update your private code with screwing up
> all of the clients that were compiled against an older version. Each
> class is given a globally unique identifier (GUID) and the DLL is
> registered in the registry. It's pretty interesting the thought
> processes that led to the development of COM
snip
> How does CORBA handle these issues?
Do not be blinded by science. It is an old problem, and there are NO new solutions, just re-hyped old ones.
The first great manifestation of 'shared' code was the Rom BIOS code we had on early desktop machines. True, the C64 did not exactly run many
apps simultaneously, but by the time we got the infamous system calls on the MAC then we had code shared by many apps, but of course it could not
change because it was in ROM, which was a bit of a pain.
That said, a program needed only to check the ROM version and it new what to expect, and could put different wrappers around calls dpending on the
ROM version.
Of course that put the work on all the calling apps, how much nicer if the called library recognized what the caller was looking for, the old version or the new version, and served accordingly.
I do not know who was the first to define or deploy such concepts (but likely to be some IBM fellow in the late 60's, certinaly long before most people realised a problem existed), BUT, I do now a system that manifests the techniques very well.
SUN RPC's are an IPC method by which a program on one machine can call a function than is part of a different application on a different machine,
and they were introduced about 15 years ago, long before people started talking about COM objects, let alone DCOM. You may never have heard of them, but they are very widely deployed in the telecomms industry, all the control and supervision of the elements of the telephone network (cellular phones, internet POP's.......) is carried out by RPC's (Gradually being replaced by CORBA).
With RPC, a call to a method on a remote machine is governed by a definition file 'gen.x'. This file contains C like function definitions,
but includes tags for identifing the function call and giving it version numbers. The server may register different version of the same call with the RPC mechanism, such that when the client machine establishes a connection with the server, the server knows which version of the function it will expose to the client. Sound familiar? In the case of RPC's this mechanism works very well, and the same concept may be found in re-hashed form, complete with volumous helpings of marketing hype.
But in essence there is no efficient way to make a call to a method if the interface has been mutated, so the basic underlying technique is to
identify the version of the interface such that the corresponding method may be called.
Now I am no expert on the internals of C++ runtime binding, but it would seem to me that I could achieve the smae goal using a standard C++
compiler with no extensions.
Consder the following:
int foo:oIt(){
return baa;
}
If I had typedeffed my int with a version number, I could later add different versions to the same library:
#typedef int fooBack
#typedef int fooBack2
fooBack foo:oIt(){
return A;
}
fooBack2 foo:oIt(){
return B;
}
This way a modified DoIt function could be included in a library, and the oveloading mechanisms would determine what gets called, depending on header file with which the program was compiled.
The point I am trying to make is that we have a simple problem that has simple solutions, that can be implementated without a whole load of new
'gunge'.
Now, a tail observation. On Linux, shared libs have filename conventions which identify the major and minor versions, e.g. libcSO.5.1.3, when an app calls the library it knows which version of the library it was compiled against, so it invokes that. Obviously nobody wants a copy of
every single release on their system, so minor versions are enetered as symbolic links to the latest greatest bug fix release.
Of course the minor numbers represent bug-fixes, the API should be the same fpr a given major number. But in reality bug-fix releases can break
because somebody who has developed against a bug-fixed version may have encountered the bug and done a workaround that causes failure on the
bugfixed verdion, in essence I now need the old and new versions n the machine.
So, in Linux I simply replace the symbiolic link with a rea version of the buffy file, how do I do something similar on 'other' platforms?
Obviously one does not want to have every minor release