适用于x86 / x64体系结构的SQLite dll

时间:2013-08-10 15:25:29

标签: c# vb.net dll sqlite

我正在VB.net中开发一个程序,并使用System.Data.SQLite预编译的二进制文件用于.NET,但它不适用于x64架构,我遇到了经典的文化问题而没有加载正确的文件。 / p>

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,可能:

  1. 添加一些指令,例如 #IFDEF (x86包含部分代码)或x64代码
  2. 加入dll只做一个。
  3. 在VB.net中引用此dll
  4. 你认为是其他更好的想法,因为我只想制作一个编辑,而不是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
    

5 个答案:

答案 0 :(得分:24)

从.NET程序集中使用SQLite有多种选择。你的第一步是转向比古老的1.0.65版本更新的东西。当前版本可以从此处下载:http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki或通过SQLite NuGet packages

如果您需要能够在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本机互操作程序集)

另一种选择是构建两个版本的应用程序,并在每个版本中引用相应的混合模式程序集。然后你最终会得到两个版本,但由于你不需要额外的子目录和native * .Interop.dlls,它们更容易处理。

在这些情况下,您不需要代码差异或32位和64位之间的可选编译。从不同的NuGet包安装可能会让您最轻松地开始。

最后一个选项是选择名为C#-SQLite的托管专用克隆:https://code.google.com/p/csharp-sqlite/。它是管理C#的SQLite引擎的一个端口,所以整个事情都是以AnyCPU运行的,并且位数不是问题。

答案 1 :(得分:6)

几年前我遇到了同样的问题,对我来说最好的解决方案是:

  • 下载图书馆的latest version
  • 您的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或类似文件中注册任何内容。

希望这有帮助。

答案 2 :(得分:1)

没有没有。

那是因为这些* .dll只是本机c / c ++ * .dll的包装器。 32位.NET应用程序必须使用32位c / c ++ dll和64位.NET应用程序必须使用64位c / c ++ dll。

我已经很久没有使用过vb.net,我不确定你是否可以像在c#中那样配置目标平台。如果可以的话,你应该这样做并采取正确的互操作dll。你应该决定是否需要32位或64位。

答案 3 :(得分:1)

@Govert和@TobiaZambon的其他答案是正确的方法。但对于其他人来说,另一种选择是使用x86版本的System.Data.Sqlite dll,只编译你的x86平台应用程序。即不要编译到AnyCPU,这意味着当它在x64机器窗口上运行时,它将以32位模式运行,并且它能够加载32位dll。

这是否有用取决于您的情况,但如果您正在构建部署到工作站的应用程序,那么这是一个非常简单的解决方案。

答案 4 :(得分:1)

使用Nuget可以轻松解决问题的现状 安装后,搜索SQLite,如:

if (new NullCheck<>(person).with(Person::getAddress).with(Address::getZipCode).isNotNull())
{
  ...
}

我使用全新的计算机和VS完成了这项工作,我需要SQLite并且做到了这一切并且一切正常。