On Tue, Jun 07, 2011 at 07:52:37AM -0500, Steve and Amy scratched on the wall: > Would someone, please, show me an example (several actual, successive > lines of code) in C (or C++) showing a proper use of > sqlite3_auto_extension()?
"Using SQLite", p209-211. http://oreilly.com/catalog/9780596521196 > I am trying to use SQLite with extensionfunctions.c, but > extensionfunctions.c lacks a function called "xEntryPoint()". > I do not know if I am actually supposed to pass a pointer to a > function called "xEntryPoint()" or not. I am leaning toward 'no' > and in reality I would think "xEntryPoint()" is merely to represent > some function found in extensionfunctions.c. You need to pass a pointer to the extension's entry point function, which is not actually named "xEntryPoint"... that's just the name of the variable that accepts the function pointer (generally, any variable that starts with "x" in the SQLite source is a function pointer). The entry point function is the same function name that is passed to sqlite3_load_extension(). Also note that the typing on sqlite3_auto_extension() pointer is wrong. You must cast the function pointer. Don't ask; I have no idea. By default, most extensions use an entry point function called "sqlite3_extension_init()". This allows sqlite3_load_extension() to automatically find the entry point when the module is loaded. You'll notice that extension-functions.c has this function, but only if COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE is defined. The issue is that if you want to compile a module in statically, all the function names need to be unique. While the dynamic library system behind sqlite3_load_extension() can deal with multiple .DLL, .so, or .dylib files that all have unique functions with the same name, the static linker cannot. You cannot build a stand-alone executable with multiple, global functions that have the same name. This is why extension-functions.c omits the default named entry point if you're trying to build it for static usage. In the case of extension-functions.c, it looks like you should just call RegisterExtensionFunctions() directly. Unfortunately, you'd have to do that every time you open a database-- which is exactly the issue sqlite3_auto_extension() is trying to avoid. If you want to use extension-functions.c with sqlite3_auto_extension(), we need to get a bit hacky with the code. First, we will want to build it for static use. To do this, comment out this line (line 111 in the current code): -------------------------------------------------------------------- #define COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE 1 -------------------------------------------------------------------- Second, the entry point functions are designed to use the external linkages, no matter how they're built. While this isn't strictly required for a static build, I think it keeps it cleaner. So we need to be sure the external linkages are always used. To do that turn this (like 123): -------------------------------------------------------------------- #ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #else #include "sqlite3.h" #endif -------------------------------------------------------------------- Into this: -------------------------------------------------------------------- #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 -------------------------------------------------------------------- Last, we need to be sure the entry point function is always built, but we need to define a globally unique name for when the module is used statically. To do that, we'll make sure the entry point function is always built, but we'll build it with a different name depending on how the module will be used. Turn this (line 1837 in the original file): -------------------------------------------------------------------- #ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE int sqlite3_extension_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){ SQLITE_EXTENSION_INIT2(pApi); RegisterExtensionFunctions(db); return 0; } #endif /* COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE */ -------------------------------------------------------------------- Into this: -------------------------------------------------------------------- #ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE int sqlite3_extension_init( #else /* COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE */ int extension_functions_init( #endif /* COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE */ sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){ SQLITE_EXTENSION_INIT2(pApi); RegisterExtensionFunctions(db); return 0; } -------------------------------------------------------------------- Finally, you can call this in your application: -------------------------------------------------------------------- sqlite3_auto_extension( (void(*)(void))extension_functions_init ); -------------------------------------------------------------------- With that done, any database you open with that application should have the extension-functions loaded and available. Just make sure you build your application, sqlite3.c and extension-functions.c all into one big executable. -j -- Jay A. Kreibich < J A Y @ K R E I B I.C H > "Intelligence is like underwear: it is important that you have it, but showing it to the wrong people has the tendency to make them feel uncomfortable." -- Angela Johnson _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users