Lately I've been writing some code to call python functions and pass objects 
that are wrapped using sip.  This is relatively easy when linking directly to 
a sip module and using it's generated api methods, however it is currently 
impossible(afaik) by only linking to sip, because there is no way to retrieve 
a pointer to a sipExportedModuleDef for a given module.

I propose this patch that adds the function api_find_module to the sipAPIDef 
struct.   With this patch you can get the sipAPIDef * from the sip modules 
python dictionary, then use api_find_module to get the registered sip module.  
From here I can get to the sipWrapperType's for the module, and use them with 
api_convert_from_new_instance, etc.

I also attached a small file showing how i use the new function.

Matt
Index: siplib/sip.h
===================================================================
--- siplib/sip.h	(revision 3753)
+++ siplib/sip.h	(working copy)
@@ -1175,6 +1175,12 @@
      * code.
      */
     int (*api_register_int_types)(PyObject *args);
+
+    /*
+     * The following are part of the public API.
+     */
+    sipExportedModuleDef * (*api_find_module)(const char * name);
+
 } sipAPIDef;
 
 
Index: siplib/siplib.c
===================================================================
--- siplib/siplib.c	(revision 3753)
+++ siplib/siplib.c	(working copy)
@@ -113,7 +113,9 @@
 static void *sip_api_import_symbol(const char *name);
 static int sip_api_register_int_types(PyObject *args);
 
+static sipExportedModuleDef * sip_api_find_module(const char * name);
 
+
 /*
  * The data structure that represents the SIP API.
  */
@@ -207,6 +209,10 @@
      * code.
      */
     sip_api_register_int_types,
+    /*
+     * The following are part of the public API.
+     */
+    sip_api_find_module,
 };
 
 
@@ -7151,3 +7157,16 @@
 
     return NULL;
 }
+
+/*
+ * Return the registered sip module's sipExportedModuleDef according
+ * to the modules name. NULL is returned if the module is not registered
+ */
+static sipExportedModuleDef * sip_api_find_module(const char *name)
+{
+	sipExportedModuleDef * em;
+    for (em = clientList; em != NULL; em = em->em_next)
+		if( strcmp(em->em_name,name) == 0 )
+			return em;
+	return 0;
+}
const sipAPIDef * getSipAPI()
{
	static const sipAPIDef * api = 0;
	if( api ) return api;

	/* Import the SIP module and get it's API.
	 * libsip does not provide a symbol for accessing the sipAPIDef object
	 * it must be retrieved through sip's python module's dictionary
	 */
	PyObject * sip_sipmod = PyImport_ImportModule((char *)"sip");
	
	if (sip_sipmod == NULL) {
		LOG_3( "getSipAPI: Error importing sip module" );
		return 0;
	}

	PyObject * sip_capiobj = PyDict_GetItemString(PyModule_GetDict(sip_sipmod),"_C_API");
	
	if (sip_capiobj == NULL || !PyCObject_Check(sip_capiobj)) {
		LOG_3( "getSipAPI: Unable to find _C_API object from sip modules dictionary" );
		return 0;
	}

	api = reinterpret_cast<const sipAPIDef *>(PyCObject_AsVoidPtr(sip_capiobj));
	return api;
}

sipExportedModuleDef * getSipModule( const char * name )
{
	const sipAPIDef * api = getSipAPI();
	if( !api ) return 0;

	sipExportedModuleDef * module = api->api_find_module( name );
	if( !module )
		LOG_5( "getSipModule: Unable to lookup module " + QString::fromLatin1(name) + " using api_find_module" );
	return module;
}

sipWrapperType * getSipWrapperType( const char * module_name, const char * typeName )
{
	sipExportedModuleDef * module = getSipModule(module_name);
	if( !module ) return 0;

	for( int i = module->em_nrtypes - 1; i >= 0; i-- ) {
		sipWrapperType * swt = module->em_types[i];
		sipTypeDef * type = swt->type;
		if( strcmp( type->td_name, typeName ) == 0 || ( type->td_cname && strcmp( type->td_cname, typeName ) == 0 ) )
			return swt;
	}

	LOG_5( "getSipWrapperType: Unabled to find " + QString::fromLatin1(typeName) + " in module " + QString::fromLatin1(module_name) );
	return 0;
}
_______________________________________________
PyKDE mailing list    [email protected]
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

Reply via email to