Hi,

I have a shared library that internally uses a statically linked sqlite for a 
few different internal tasks. Amongst these there is some code that provides a 
few virtual tables. I would like to extend the interface of the library so that 
as well as it’s normal interface, it can be accessed as an sqlite extension 
through some of these virtual tables. This will allow my library to be used in 
two ways:

a) Through its normal C interface.
b) From an sqlite3 extension loadable from the sqlite3 client app, or the R or 
python interfaces to sqlite3.

The problem is how to build the internal code that accesses sqlite3, including 
the virtual table code that I also want to make available through the 
extension. For the virtual table code I think I would need to build two copies, 
one with SQLITE_CORE defined (to be used internally), and the other without (to 
be used in case b). Doing this, in case b, I would suffer the problems I have 
read about where there would be two copies of the static global that implements 
the posix locking workaround. Although in my use case it is almost certain this 
would not cause a problem (I can’t envisage a use case where both my statically 
linked sqlite3 and the one being used at the interface layer would open the 
same db). It still feels like an ugly solution.

My thought instead is to build all of sqlite code using sqlite3ext.h and 
without SQLITE_CORE defined, and in case a, dynamically load an sqlite3 
library. However i need to get access to the sqlite3_api_routines pointer 
within whichever sqlite3 library is being used. My question is how to do this?

In case b, the pointer is passed when the extension is first loaded, and I can 
pass it through to the rest of my library. For case a I’m struggling a bit. The 
best I can figure is:

(Assume I have called dlopen/LoadLibrary and can access symbols with 
dlsym/GetProcAddress)

1. Set up a fake extension function whose purpose is to capture the sqlite3Apis 
pointer passed to xInit within sqlite3AutoLoadExtensions.
2. Use dlsym/GetProcAddress to find sqlite3_auto_extension, 
sqlite3_cancel_auto_extension, sqlite3_open_v2, sqlite3_close.
3. Register my extension with sqlite3_auto extension.
4. Open an in memory database to load the extension and capture the 
sqlite3_api_routines pointer.
5. Close the database.
6. Cancel the auto extension.

My questions are:

1) Am I missing anything, i.e. does this work.
2) Will it be guaranteed in the future that the sqlite3_api_routines pointer 
will be passed to the extensions loaded by sqlite3_auto_extension.
3) Is there a better way to do this as it feels a little hacky.

Thanks,
Kevin
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to