Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

dlopen & co/Plugin Qt SQLite : charger une library déjà charger par un plugin, résolution de symbole.

1 réponse
Avatar
me
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

1 réponse

Avatar
Toxico Nimbus
Le 12/10/2012 21:16, me a écrit :
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 :
:~> 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 :


[SNIP]

Les symboles manquants sont toujours résolus. Le fait de donner
RTLD_LAZY comme drapeau ne fait que reporter la résolution (en fait
c'est utile uniquement si tu as plusieurs dlopen.