2015-07-30 3 views
-1

Я использую SQLite в качестве механизма базы данных в своем приложении, но в то же время приложение должно быть кросс-платформенным, поэтому я решил использовать Mono.Data.Sqlite. И это то, что я сделал:Mono.Data.Sqlite исключает исключения

  • Установил последнюю версию Mono (4.0.2 SR 2), скопированный Mono.Data.Sqlite.dll из каталога Моно (net4_5) в мой проект в Visual Studio 2015

  • Загружена и скопирована предварительно скомпилированная библиотека sqlite3.dll.

И тогда я написал простое приложение:

 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(); 
     } 

Но я столкнулся с некоторыми вопросами:

  • Во-первых, когда я использую Источник данных = файл : {0} в строке подключения генерирует исключение: «Форматы URI не поддерживаются». Замена его на URI = файл: {0} помогает, но почему первый вариант не работает?

  • Во-вторых, когда я называю conn.ChangePassword ("testpassword") он бросает исключение: System.EntryPointNotFoundException: Не удается найти точку входа с именем "sqlite3_rekey" в DLL "sqlite3"

  • Третий , используя URI = файл: {0}; Password = testpassword с уже зашифрованной базы данных выдает исключение: System.EntryPointNotFoundException: Не удается найти точку входа с именем "sqlite3_key" в DLL "sqlite3"

На самом деле это не происходит с официальной оболочкой для SQLite, но происходит с Mono.

P.S. обертка Mono работает нормально, когда я не использовать шифрование и Источник данных = файл: {0} вместо URI = файл: {0}

P.S.S. Windows 10, Visual Studio 2015 + последняя версия Mono и SQLite

+0

Второй и третий пункты, потому что он не может найти DLL родной, что версия Mono пытается p/invoke. Простое копирование dll на базе CIL недостаточно. – SushiHangover

+0

Я уже упоминал, что я скопировал собственную библиотеку sqlite и, кроме того, прочитал ли вы постскриптум? – maque

ответ

0

Для первой проблемы конвертируйте свой URI в локальный путь к файлу; new Uri(databaseFileURI).LocalPath. file:// или file: не используется Sqlite и лишен кода помощника C#, см. Код в «Mono.Data.Sqlite_2.0/SQLiteConnection.cs».

Для второго/третьего выпусков:

sqlite3 родной Lib, что у вас есть, как представляется, не соответствуют операторы импорта DLL Моно, вы можете использовать bindump /EXPORTS, чтобы подтвердить это. Mono DllImports и соответствующий SQLite .h экспортируется следующим образом:

ПРИМЕЧАНИЕ. Это, конечно, предполагает, что у вас есть правильный ARCH для родной DLL, и вы не компилируете Uni-приложение в Windows.

Grep'ing из источника "Mono.Data.Sqlite_2.0/UnsafeNativeMethods.CS»

Во-вторых, когда я называю conn.ChangePassword ("testpassword") он бросает исключение: System.EntryPointNotFoundException: Не удается найти запись пункт под названием "sqlite3_rekey" в 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 = файл: {0}; Password = testpassword с уже зашифрованной базы данных выдает исключение: System.EntryPointNotFoundException: Не удается найти точку входа назвал "sqlite3_key" в 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 определяет:

... 
SQLITE_API int SQLITE_STDCALL sqlite3_rekey 
... 
SQLITE_API int SQLITE_STDCALL sqlite3_key 
... 
+0

Спасибо, но используя ** Data Source = {0} ** в строке соединения теперь работает. BTW, около 2/3 вопросов - так мне нужно найти правильную DLL, которая содержит эти точки входа? – maque

+0

Если у родной SQL-библиотеки, у которой у вас нет этих точек входа, тогда да. Я не уверен, откуда у вас есть, но есть замечания на сайте sqlite.org о компиляции его для Mono ... Если нет жесткой причины использовать сборки Mono, вы можете просто взять один из Sqlite PCL nugets (или связанный источник), как SQLite-net PCL от praeclarum – SushiHangover

+0

Я загрузил его с официального сайта: ** 32-разрядная DLL (x86) для SQLite verison 3.8.11.1 ** (раздел * Предварительно скомпилированные бинарные файлы для Windows *) – maque

Смежные вопросы