Mono.Data.Sqlite引发异常 [英] Mono.Data.Sqlite throws exceptions

查看:756
本文介绍了Mono.Data.Sqlite引发异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中使用SQLite作为数据库引擎,但同时应用程序必须是跨平台的,因此我决定使用Mono.Data.Sqlite.这就是我所做的:

I'm using SQLite as database engine in my app, but at the same time the application must be cross-platform, so i have decided to use Mono.Data.Sqlite. And this what i did:

  • 安装了最新版本的Mono(4.0.2 SR 2),将Mono.Data.Sqlite.dll从Mono的目录(net4_5)复制到我在Visual Studio 2015中的项目中

  • Installed the latest version of Mono (4.0.2 SR 2), copied Mono.Data.Sqlite.dll from Mono's directory (net4_5) to my project in Visual Studio 2015

下载并复制了预编译的sqlite3.dll库.

Downloaded and copied precompiled sqlite3.dll library.

然后我写了一个简单的应用程序:

And then i wrote a simple app:

        const string databaseFileName = "somedata.db";
        var path = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + databaseFileName;

        if (!File.Exists(path)) SqliteConnection.CreateFile(databaseFileName);

        var connString = string.Format("Data Source=file:{0}", databaseFileName);

        using (var conn = new SqliteConnection(connString))
        {
            conn.Open();

            /* Some code */
            conn.ChangePassword("testpassword");
            conn.Close();
        }

但是我面临一些问题:

  • 首先,当我在连接字符串中使用 Data Source = file:{0} 时,它将引发异常:不支持URI格式".将其替换为 URI = file:{0} 会有所帮助,但是为什么第一个选项不起作用?

  • First, when i'm using Data Source=file:{0} in connection string, it throws an exception: "URI formats are not supported". Replacing it to URI=file:{0} helps, but why the first option doesn't work?

其次,当我调用 conn.ChangePassword("testpassword")时,它将引发异常:System.EntryPointNotFoundException:无法在DLL"sqlite3"中找到名为"sqlite3_rekey"的入口点

Second, when i call conn.ChangePassword("testpassword") it throws an exception: System.EntryPointNotFoundException: Unable to find an entry point named "sqlite3_rekey" in DLL "sqlite3"

第三,对已加密的数据库使用 URI = file:{0}; Password = testpassword 会引发异常:System.EntryPointNotFoundException:无法找到名为"sqlite3_key"的入口点在DLL"sqlite3"中

Third, using URI=file:{0};Password=testpassword with the already encrypted database throws an exception: System.EntryPointNotFoundException: Unable to find an entry point named "sqlite3_key" in DLL "sqlite3"

SQLite的官方包装器实际上并没有发生这种情况,而Mono的情况则发生了这种情况.

It doesn't actually happen with official wrapper for SQLite, but happens with Mono's.

P.S.当我不使用加密和数据源=文件:{0} 而不是 URI =文件:{0}

P.S. Mono's wrapper works normally when i don't use encryption and Data Source=file:{0} instead of URI=file:{0}

P.S.S. Windows 10,Visual Studio 2015 +最新版本的Mono和SQLite

P.S.S. Windows 10, Visual Studio 2015 + latest version of Mono and SQLite

推荐答案

对于第一个问题,请将您的URI转换为本地文件路径; new Uri(databaseFileURI).LocalPath. Sqlite不使用file://file:,C#辅助代码将其剥离,请参见"Mono.Data.Sqlite_2.0/SQLiteConnection.cs"中的代码.

For the first issue, convert your URI to a local file path; new Uri(databaseFileURI).LocalPath. The file:// or file: is not used by Sqlite and stripped by the C# helper code, see the code in "Mono.Data.Sqlite_2.0/SQLiteConnection.cs".

对于第二个/第三个问题:

For the second/third issues:

您显示的sqlite3本机lib与Mono的dll导入语句不匹配,您可以使用bindump /EXPORTS进行确认. Mono DllImports和匹配的SQLite .h导出如下:

The sqlite3 native lib that you have appears to not match the Mono's dll import statements, you can use bindump /EXPORTS to confirm this. The Mono DllImports and the matching SQLite .h exports follows:

注意:当然,这假定您具有本机dll的正确ARCH,并且您没有在Windows中编译Uni-app.

NOTE: This of course assumes you are have the correct ARCH for the native dll and you are not compiling a Uni-app in Windows.

重新找出"Mono.Data.Sqlite_2.0/UnsafeNativeMethods.cs"的源代码

Grep'ing out the source of "Mono.Data.Sqlite_2.0/UnsafeNativeMethods.cs"

第二,当我调用conn.ChangePassword("testpassword")时,它会抛出一个 异常:System.EntryPointNotFoundException:无法找到条目 DLL"sqlite3"中名为"sqlite3_rekey"的点

Second, when i call conn.ChangePassword("testpassword") it throws an exception: System.EntryPointNotFoundException: Unable to find an entry point named "sqlite3_rekey" in DLL "sqlite3"

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_key(IntPtr db, byte[] key, int keylen);

第三,使用URI = file:{0}; Password = testpassword和已经 加密的数据库引发异常: System.EntryPointNotFoundException:无法找到入口点 DLL"sqlite3"中名为"sqlite3_key"

Third, using URI=file:{0};Password=testpassword with the already encrypted database throws an exception: System.EntryPointNotFoundException: Unable to find an entry point named "sqlite3_key" in DLL "sqlite3"

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_rekey(IntPtr db, byte[] key, int keylen);

匹配的sqlite.h定义:

The matching sqlite.h defines:

...
SQLITE_API int SQLITE_STDCALL sqlite3_rekey
...
SQLITE_API int SQLITE_STDCALL sqlite3_key
...

这篇关于Mono.Data.Sqlite引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆