Bonjour,
Note : Il n'y a pas vraiment une question sur le C++, c'est plus une histoire de
compilateur et de linker, je ne sais pas ou poster, dirigez moi sur une autre
forum si nᅵcessaire.
J'ai un programme ᅵcrit avec Qt et utilisant le plugin SQLite.
Dans ce programme j'ai besoins d'ajouter des fonctions utilisables depuis une
requᅵte sql.
J'ai fait divers hacks et je suis arrivᅵ ᅵ un rᅵsultat ᅵtonnant, je m'explique :
Initialement je voulais accᅵder ᅵ la fonction sqlite3_create_function en
utilisant le trio dlopen/dlsym/dlclose
Mais je me suis rendu compte qu'il n'ᅵtait pas utile d'utiliser dlsym et je suis
surpris que mon programme marche, seul l'appel ᅵ dlopen suffi pour que je puisse
utiliser la fonction sqlite3_create_function
Je vous poste le code ci dessous, mais j'aimerais avoir votre avis sur la
pᅵrennitᅵ de ce code et de sa portabilitᅵ (ᅵ l'exception de MSWIndows) ?
Et ᅵgalement comment se fait il qu'en invoquant uniquement dlopen je peux
utiliser la fonction sqlite3_create_function, dont l'adresse n'est pas rᅵsolue ᅵ
la compilation ?
Voici la version de mon compilateur :
kangs@kangs:~> g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.5/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --
mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-
languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-
gxx-include-dir=/usr/include/c++/4.5 --enable-ssp --disable-libssp --disable-
plugin --with-bugurl=
http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --
disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --
enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --
enable-version-specific-runtime-libs --program-suffix=-4.5 --enable-linux-futex
--without-system-libunwind --enable-gold --with-plugin-ld=/usr/bin/gold --with-
arch-32=i586 --with-tune=generic --build=x86_64-suse-linux
Thread model: posix
gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux)
Code :
En tᅵte :
#ifndef SQLITELOADUSERFUNCTION_H
#define SQLITELOADUSERFUNCTION_H
#include <QVariant>
// Pour ce hack j'irais demander l'avis sur la mailing-list de sqlite.
#define SQLITE_API extern
#define SQLITE_EXTERN
#include <sqlite3.h>
namespace sqlite
{
class LoadUserFunction
{
public:
LoadUserFunction( QVariant sqliteDriverHandle, char const* libsqlite =
"libsqlite3.so" );
~LoadUserFunction();
typedef void (*SQLiteUserFunc)(sqlite3_context*,int, sqlite3_value**);
bool valid() const { return sqliteHandle_ != NULL && libsqliteHandle_ != NULL;
}
bool load( char const* funcName, SQLiteUserFunc userFunc );
private:
sqlite3* sqliteHandle_;
void* libsqliteHandle_;
#if 0
typedef int (*ptr_sqlite3_create_function)(sqlite3*,const
char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void
(*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)
(sqlite3_context*));
ptr_sqlite3_create_function sqlite3_create_function_;
#endif
};
} // namespace sqlite
#endif // SQLITELOADUSERFUNCTION_H
Fichier source :
#include "sqliteloaduserfunction.h"
#include <dlfcn.h> // Fonctions dl...
namespace sqlite
{
LoadUserFunction::LoadUserFunction( QVariant sqliteDriverHandle, char const*
libsqlite )
: sqliteHandle_( NULL )
, libsqliteHandle_( NULL )
{
if ( sqliteDriverHandle.isValid() && qstrcmp( sqliteDriverHandle.typeName(),
"sqlite3*" ) == 0 )
sqliteHandle_ = *static_cast<sqlite3**>( sqliteDriverHandle.data() );
if ( sqliteHandle_ != NULL )
{
libsqliteHandle_ = dlopen( libsqlite, RTLD_LAZY );
//if ( libsqliteHandle_ != NULL )
// *(void **)(&sqlite3_create_function_) = dlsym( libsqliteHandle_,
"sqlite3_create_function" );
}
}
LoadUserFunction::~LoadUserFunction()
{
if ( libsqliteHandle_ != NULL )
dlclose( libsqliteHandle_ );
}
bool LoadUserFunction::load( char const* funcName, SQLiteUserFunc userFunc )
{
return sqlite3_create_function( sqliteHandle_, funcName, 1, SQLITE_ANY, NULL,
userFunc, NULL, NULL ) == 0;
}
} // namespace sqlite