Interface versioning
kde at jowenn.at
kde at jowenn.at
Thu Jul 18 23:53:00 BST 2002
Hi
I came across a problem, which would need interface versioning. It's needed
eg for someplugins which are compiled against modified interfaces. I mean
old plugins work with newer applications, but not vice versa.
I think that could be used kde wide, so I started to enhance the klibloader
and the componentfactory. It's not really tested yet, but since I don't
know if others like that approach, I post my patches here, so that they can
be discussed before I put any further work into it.
Kind regards
Joseph Wenninger
-------------- next part --------------
Index: componentfactory.h
===================================================================
RCS file: /home/kde/kdelibs/kparts/componentfactory.h,v
retrieving revision 1.10
diff -u -3 -p -r1.10 componentfactory.h
--- componentfactory.h 2002/04/09 12:20:44 1.10
+++ componentfactory.h 2002/07/18 22:38:18
@@ -28,6 +28,8 @@ namespace KParts
* for creating components</li>
* <li><code>ErrNoComponent</code> - the factory does not support creating
* components of the specified type</li>
+ * <li><code>ErrWrongVersion</code> - The used interface version is not within the
+ * allowed range version1<=version<=version2</li>
* </ul>
*/
enum ComponentLoadingError { ErrNoServiceFound = 1,
@@ -35,7 +37,7 @@ namespace KParts
ErrNoLibrary,
ErrNoFactory,
ErrNoComponent };
-
+ enum ExtendedComponentLoadingError {ErrWrongVerson=6};
/**
* This template function allows to ask the given factory to create an
* instance of the given template type.
@@ -149,6 +151,54 @@ namespace KParts
}
return res;
}
+
+
+
+ template <class T>
+ static T *createVersionedInstanceFromLibrary( const char *libraryName, int version1=0, int version2=0,QObject
+ *parent = 0,
+ const char *name = 0,
+ const QStringList &args = QStringList(),
+ int *error = 0 )
+ {
+ KLibrary *library = KLibLoader::self()->library( libraryName );
+ if ( !library )
+ {
+ if ( error )
+ *error = ErrNoLibrary;
+ return 0;
+ }
+
+ if (version2)
+ if ( ! ( (version2>=library->interfaceVersion()) &&
+ (version1<=library->interfacVersion())))
+ {
+ library->unload();
+ if (error)
+ *error=ErrWrongVersion;
+ return 0;
+ }
+
+ KLibFactory *factory = library->factory();
+ if ( !factory )
+ {
+ library->unload();
+ if ( error )
+ *error = ErrNoFactory;
+ return 0;
+ }
+ T *res = createInstanceFromFactory<T>( factory, parent, name, args );
+ if ( !res )
+ {
+ library->unload();
+ if ( error )
+ *error = ErrNoComponent;
+ }
+ return res;
+ }
+
+
+
template <class T>
static T *createPartInstanceFromLibrary( const char *libraryName,
-------------- next part --------------
Index: klibloader.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/klibloader.cpp,v
retrieving revision 1.59
diff -u -3 -p -r1.59 klibloader.cpp
--- klibloader.cpp 2002/05/21 10:46:00 1.59
+++ klibloader.cpp 2002/07/18 22:38:40
@@ -180,6 +180,24 @@ KLibFactory* KLibrary::factory()
return m_factory;
}
+int KLibrary::interfaceVersion()
+{
+ QCString symname;
+ symname.sprintf("usedInterfaceVersion_%s", name().latin1() );
+
+ void* sym = symbol( symname );
+ if ( !sym )
+ {
+ kdWarning(150) << "KLibrary: The library " << name() << " does not offer an usedInterfaceVersion_" << name() << " function" << endl;
+ return 0;
+ }
+
+ typedef int (*t_func)();
+ t_func func = (t_func)sym;
+ return func();
+
+}
+
void* KLibrary::symbol( const char* symname ) const
{
void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname );
Index: klibloader.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/klibloader.h,v
retrieving revision 1.51
diff -u -3 -p -r1.51 klibloader.h
--- klibloader.h 2002/05/21 10:46:00 1.51
+++ klibloader.h 2002/07/18 22:38:40
@@ -38,6 +38,10 @@ class KLibraryPrivate;
#define K_EXPORT_COMPONENT_FACTORY( libname, factory ) \
extern "C" { void *init_##libname() { return new factory; } };
+#define K_EXPORT_VERSIONED_COMPONENT_FACTORY( libname, factory , version) \
+ extern "C" { void *init_##libname() { return new factory; } \
+ int usedInterfaceVersion_##version() { return version;} };
+
/**
* @short Represents a dynamically loaded library.
*
@@ -72,6 +76,11 @@ public:
* @return The factory of the library if there is any.
*/
KLibFactory* factory();
+
+ /**
+ * @return The version of the interface the library has been linked with. 0 if unknown
+ */
+ int interfaceVersion();
/**
* Looks up a symbol from the library. This is a very low level
More information about the kde-core-devel
mailing list