SQLite dll для архитектуры x86/x64

Я разрабатываю программу на VB.net и использую System.Data.SQLite Предварительно скомпилированные бинарные файлы для .NET, однако она не работает для x64-архитектур, и я получение классической проблемы с культурой, а не загрузка правильного файла.

System.BadImageFormatException: 
Could not load file or assembly 'System.Data.SQLite, Version=1.0.65.0, Culture=neutral,
 PublicKeyToken=db937bc2d44ff139' or one of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'System.Data.SQLite,
 Version=1.0.65.0,
 Culture=neutral, 
 PublicKeyToken=db937bc2d44ff139'

Есть ли способ использовать только одну DLL, возможно:

  • Добавьте некоторые директивы типа #IFDEF (x86 включает часть кода) или код x64
  • Присоединить dll, чтобы сделать только один.
  • Ссылка на эту DLL в VB.net

Как вы думаете, другая идея Idea, поскольку я хотел бы сделать только одну компиляцию, а не одну для x32 и другую для x64.

Например (32 бита):

Private Shared Sub OpenConection(ByRef Conn As SQLite.SQLiteConnection)
    Conn = New SQLite.SQLiteConnection("Data Source=" & System.Environment.CurrentDirectory & "\database.db")
    Conn.Open()
End Sub

Private Shared Sub CloseConection(ByRef Conn As SQLite.SQLiteConnection)
    Conn.Close()
    Conn.Dispose()
    Conn = Nothing
End Sub

Public Shared Function ReturnSelect(ByVal DataTAbleName As String, ByVal sQuery As String, ByVal sWhere As String) As Data.DataTable
    Dim lDT As New DataTable
    Dim lTA As New SQLite.SQLiteDataAdapter
    If DataTAbleName Is Nothing Then Return New DataTable(DataTAbleName)
    Try
        OpenConection(conexion)
        lTA = New SQLite.SQLiteDataAdapter("SELECT " & sQuery & " FROM  " & DataTAbleName & IIf(sWhere <> String.Empty, " WHERE ", "") & sWhere, conexion)
        lTA.Fill(lDT)
    Catch ex As Exception
        Throw ex
    Finally
        CloseConection(conexion)
        lTA.Dispose()
        lTA = Nothing
    End Try
    Return lDT
End Function

Как изменить это на 64-битную архитектуру? Возможно, включая как 32, так и 64 dll, а в функциях что-то вроде

Try
    Instance = Me
    'Check If Homidom Run in 32 or 64 bits
    If IntPtr.Size = 8 Then _OsPlatForm = "64" Else _OsPlatForm = "32"
    'continue code

Catch ex As Exception
    ' ex.Message
End Try

Ответ 1

Существуют различные варианты использования SQLite из сборки .NET. Ваш первый шаг - перейти к чему-то более новому, чем древняя версия 1.0.65. Текущие версии можно скачать здесь: http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki или через SQLite NuGet пакеты.

Если вам нужно работать под 32-разрядной и 64-разрядной версиями, один вариант - использовать опцию предварительной загрузки исходной библиотеки, где вы распространяете собственные двоичные файлы в отдельных каталогах, чтобы он выглядел так:

  • \App.exe(дополнительная, исполняемая сборка приложения с управляемым только)
  • \App.dll(дополнительная сборка библиотеки только для управляемых приложений)
  • \System.Data.SQLite.dll(требуется, сборка только для управляемого управления)
  • \System.Data.SQLite.Linq.dll(необязательно, только для LINQ-сборки)
  • \x86\SQLite.Interop.dll(требуется, встроенная сборка x86)
  • \x64\SQLite.Interop.dll(требуется, встроенная сборка x64)

Другой вариант - создать две версии вашего приложения, и в каждой версии вы ссылаетесь на соответствующую сборку в смешанном режиме. Тогда у вас будет две версии, но их немного проще справиться, поскольку вам не нужен дополнительный подкаталог и родные *.Interop.dlls.

В этих случаях вам не нужны никакие разности кода или необязательная компиляция между 32-битными и 64-битными. Установка из разных пакетов NuGet, вероятно, облегчит вам работу.

Конечным вариантом является переход к управляемому только клону С# -SQLite: https://code.google.com/p/csharp-sqlite/. Это порт движка SQLite для управления С#, поэтому все это работает как AnyCPU, а битность не является проблемой.

Ответ 2

У меня была такая же проблема несколько лет назад, и для меня лучшее решение:

  • загрузите последнюю версию библиотеки
  • в вашем пути к bin помещается только System.Data.SQLite.dll и в конечном итоге System.Data.SQLite.Linq.dll
  • поместите библиотеку x86 SQLite.Interop.dll в c:\Windows\SysWOW64
  • поместите библиотеку x64 SQLite.Interop.dll в c:\Windows\System32
  • скомпилируйте ваш проект как Any CPU, ссылающийся только на System.Data.SQLite (dll в путь к bin)
  • пользоваться

Таким образом, среда .NET будет автоматически загружать правильную (x86 vs x64) библиотеку во время выполнения без регистрации чего-либо в GAC или аналогичном.

Надеюсь, что это поможет.

Ответ 3

Нет никого.

Это потому, что эти *.dll являются только оболочками для родных c/С++ *.dll. И 32-разрядное приложение .NET должно использовать 32-битную dll c/С++ и 64-разрядное .NET-приложение должно использовать 64-битную c/С++ dll.

Я долгое время не использовал vb.net, я не уверен, что вы можете настроить целевую платформу, как вы можете сделать в С#. Если вы можете, вы должны сделать это и взять правильную DLL. И вы должны решить, нужны ли вам 32-битные или 64-разрядные версии.

Ответ 4

Другие ответы здесь @Govert и @TobiaZambon - правильный путь. Но для кого-либо еще читающего, другой вариант заключается в использовании x86-версии dll System.Data.Sqlite и только компиляции вашего приложения для платформы x86. то есть не компилировать AnyCPU, что означает, что при запуске на компьютере с процессором x64 он будет запускаться в 32-разрядном режиме, и он сможет загрузить 32-разрядную dll.

Будет ли это полезно, будет зависеть от вашей ситуации, но если вы создаете приложение, развернутое на рабочие станции, это довольно простое решение.

Ответ 5

Состояние вопроса можно легко решить, используя Nuget После установки найдите SQLite, например:

PM> Install-Package System.Data.SQLite 

Я сделал это, используя совершенно новый компьютер и VS, мне нужен SQLite, и все это работало нормально.