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