SQLitePCL.raw
SQLitePCL.raw copied to clipboard
trying to load libe_sqlite3.so from /usr/lib (reopen)
@ericsink @bricelam
in continuation to https://github.com/dotnet/efcore/issues/20462
I am opening the issue again because i am stuck, and have no other channel to ask for some guidance.
i need the native library libe_sqlite3.so to run from /usr/lib and not from the relative path like ../runtimes/linux-x64/native/libe_sqlite3.so
following this hint from eric: https://github.com/ericsink/SQLitePCL.raw/issues/325
I have edited the /src/common/batteries_v2.cs file, added the code:
class NativeLibraryAdapter : IGetFunctionPointer
{
readonly IntPtr _library;
public NativeLibraryAdapter(string name)
=> _library = NativeLibrary.Load(name);
public IntPtr GetFunctionPointer(string name)
=> NativeLibrary.TryGetExport(_library, name, out var address)
? address
: IntPtr.Zero;
}
to class:
static class Batteries_V2
then changed the
static void DoDynamic_cdecl
method to use
SQLite3Provider_dynamic_cdecl
.Setup("e_sqlite3", new NativeLibraryAdapter("e_sqlite3"));
SQLitePCL.raw.SetProvider(new SQLite3Provider_dynamic_cdecl());
and, of course nothing is working...
So, is there a different way for me to load the native library from /usr/lib? even if it is hardcoded path and file name, its fine, I just cant find the place for this to work.
Thank you in advance.
When trying to load from /usr/lib, you probably want the name of the library to be sqlite3
instead of e_sqlite3
.
I use the e_sqlite3
name specifically to avoid clashes with other instances of the library.
I tried both, as i have both libe_sqlite3.so and libsqlite3.so in the /usr/lib
Just to confirm, you're on .NET Core 3.x, right?
yes
Attached is a little sample app that demonstrates what you are trying to do.
In this example, I dropped libe_sqlite3.so in my home directory and used that path to access it, but you can use whatever path you want.
Thank you, the little program works, do i have to use "ugly" or its just for debugging? I will try to integrate it again.
Nah, ugly was just a convenient (for me) way to write the little test at the bottom to verify that it works.
i changed the batteries_v2.cs file like this:
please note that I had to change the code to this :
class NativeLibraryAdapter : IGetFunctionPointer
{
readonly IntPtr _library;
System.Reflection.Assembly assy = typeof(SQLitePCL.raw).Assembly;
public NativeLibraryAdapter(string name)
=> _library = NativeLibrary.Load(name,assy,0);
public IntPtr GetFunctionPointer(string name)
=> NativeLibrary.TryGetExport(_library, name, out var address)
? address
: IntPtr.Zero;
}
due to exception in the build:
SQLitePCLRaw.provider.dynamic_cdecl -> C:\GIT\SQLitePCL.raw\src\SQLitePCLRaw.provider.dynamic_cdecl\bin\Release\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll C:\GIT\SQLitePCL.raw\src\common\batteries_v2.cs(44,33): error CS7036: There is no argument given that corresponds to the required formal parameter 'assy' of 'NativeLibrary.Load(string, Assembly, int)' [C:\GIT\SQLitePCL.raw\src\SQLitePCLRaw.batteries_v2.e_sqlite3.dynamic\SQLitePCLRaw.batteries_v2.e_sqlite3.dynamic.csproj]
after i changed the code and compiled, i take the files from ..\SQLitePCL.raw\src\SQLitePCLRaw.provider.dynamic_cdecl\bin\Release\netstandard2.0
and replace only SQLitePCLRaw.core.dll and SQLitePCLRaw.provider.dynamic_cdecl.dll files in my folder, run my app, and i get this error:
An assembly specified in the application dependencies manifest was not found: package: 'SQLitePCLRaw.lib.e_sqlite3', version: '2.0.2' path: 'runtimes/linux-x64/native/libe_sqlite3.so'
Why do you have a batteries_v2.cs file?
The sample I attached does not.
where else can I integrate the code inside the SQLitePCL.raw code? as far as i understand there is a chain of dependencies, when in the higher c# code someone access the database, it is calling the Microsoft.Data.Sqlite.dll which is calling the SQLitePCLRaw.core.dll which is calling the provider that trying to find the native so file.
and the only place i found which is calling to SQLitePCL.raw.SetProvider is in batteries file
The batteries/bundles are convenience packages that call SetProvider for you. In your case, you want to call SetProvider yourself, as shown in the sample I uploaded.
I'm pretty sure you should be using this version of Microsoft.Data.Sqlite if you are not already:
https://www.nuget.org/packages/Microsoft.Data.Sqlite.Core/
The difference between Microsoft.Data.Sqlite.Core and regular Microsoft.Data.Sqlite is that the former doesn't take a dependency on a bundle, so that you can initialize SQLitePCLRaw for yourself.
@ericsink, I need your help. How can I use this in a class library that uses "netstandard2.0;net461;monoandroid90;monoandroid10.0;xamarin.ios10" ?
@angelrishi That question is too vague. You need to open a new issue and post complete information about what trouble you are having.
@ericsink Apologies for not being clear. We are using "Azure.Mobile.Client" for offline sync in Xamarin.Forms. I purchased SEE from sqlite team (as I wanted to use SEE instead of SQLCipher). I then created a custom build of SQLite and placed in XAMARIN FORMS under the Android project under "/lib/x86/libsqliteX.so". Similarly added appropriate build file in Xamarin's iOS project too. I found that "Microsoft.Azure.Mobile.Client.SQLiteStore" uses "SQLitePCLRaw.bundle_green" and they use:
SQLitePCLRawHelpers.GetSqliteConnection(dbPath) This function further calls: Batteries_V2.Init();
This INIT call infact would call:
For Android: SQLitePCLRaw.provider.e_sqlite3 SQLitePCLRaw.lib.e_sqlite3.android
For iOS: SQLitePCLRaw.provider.sqlite3 I guess.
Now, as we're using a custom build of SQLITE as .so file in Android, I cannot use Batteries_V2.Init();. Instead, I removed "SQLitePCLRaw.bundle_green" and installed SQLPclRaw.core and SQLite3Provider_dynamic_cdecl.
Then I removed Batteries_V2.Init(); and replaced it with:
SQLite3Provider_dynamic_cdecl.Setup("sqlite3", new NativeLibraryAdapter("libsqliteX.so")); raw.SetProvider(new SQLite3Provider_dynamic_cdecl());
For NativeLibraryAdapter, I am using SQLITEPCL.NATIVELIBRARY as this is not .net core:
class NativeLibraryAdapter : IGetFunctionPointer { readonly IntPtr _library;
public NativeLibraryAdapter(string name)
=> _library = NativeLibrary.Load(name, typeof(NativeLibraryAdapter).Assembly, 0);//Assembly.GetExecutingAssembly()
public IntPtr GetFunctionPointer(string name)
=> NativeLibrary.TryGetExport(_library, name, out var address)
? address
: IntPtr.Zero;
}
The things are not working. The file is not being read and the following line: SQLite3Provider_dynamic_cdecl.Setup("sqlite3", new NativeLibraryAdapter("libsqliteX.so"));
breaks the Mobile APP.
Could you please give me a direction that how I can use "libsqliteX.so" in Xamarin Android using SQLitePCLRawHelpers?
Your guidance will help me a lot. Please guide.
Thanks.
Angel
I can't find libe_sqlite.so file anywhere and this is the only forum I came into. Where can I find this library for both armv7 and arm64 architectures?
@bartutiryakioglu In the nuget package sqlitepclraw.lib.e_sqlite3
https://www.nuget.org/packages/SQLitePCLRaw.lib.e_sqlite3
Closing old/stale issue. If there is anything here that still needs attention, please open a new issue.