ericsink / SQLitePCL.raw

A Portable Class Library (PCL) for low-level (raw) access to SQLite
Apache License 2.0
525 stars 109 forks source link

trying to load libe_sqlite3.so from /usr/lib (reopen) #341

Closed IAmJustAQuestion closed 2 years ago

IAmJustAQuestion commented 4 years ago

@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.

ericsink commented 4 years ago

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.

IAmJustAQuestion commented 4 years ago

I tried both, as i have both libe_sqlite3.so and libsqlite3.so in the /usr/lib

ericsink commented 4 years ago

Just to confirm, you're on .NET Core 3.x, right?

IAmJustAQuestion commented 4 years ago

yes

ericsink commented 4 years ago

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.

g341.zip

IAmJustAQuestion commented 4 years ago

Thank you, the little program works, do i have to use "ugly" or its just for debugging? I will try to integrate it again.

ericsink commented 4 years ago

Nah, ugly was just a convenient (for me) way to write the little test at the bottom to verify that it works.

IAmJustAQuestion commented 4 years ago

i changed the batteries_v2.cs file like this:

batteries_v2.cs.txt

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'
ericsink commented 4 years ago

Why do you have a batteries_v2.cs file?

The sample I attached does not.

IAmJustAQuestion commented 4 years ago

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

ericsink commented 4 years ago

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.

angelrishi commented 2 years ago

@ericsink, I need your help. How can I use this in a class library that uses "netstandard2.0;net461;monoandroid90;monoandroid10.0;xamarin.ios10" ?

ericsink commented 2 years ago

@angelrishi That question is too vague. You need to open a new issue and post complete information about what trouble you are having.

angelrishi commented 2 years ago

@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

bartutiryakioglu commented 2 years ago

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?

ericsink commented 2 years ago

@bartutiryakioglu In the nuget package sqlitepclraw.lib.e_sqlite3

https://www.nuget.org/packages/SQLitePCLRaw.lib.e_sqlite3

ericsink commented 2 years ago

Closing old/stale issue. If there is anything here that still needs attention, please open a new issue.