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