【问题标题】:SQLite dll for x86/x64 architectures用于 x86/x64 架构的 SQLite dll
【发布时间】:2013-08-10 15:25:28
【问题描述】:

我正在 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,也许:

  1. 添加一些指令,如 #IFDEF(x86 包含部分代码)或 x64 代码
  2. 加入 dll 以仅生成一个。
  3. 在 VB.net 中引用此 dll

你认为还有其他更好的想法吗,因为我只想编译一个,而不是一个用于 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

【问题讨论】:

    标签: c# vb.net dll sqlite


    【解决方案1】:

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

    如果您需要能够在 32 位和 64 位下运行,一种选择是使用 native library pre-loading 选项,您可以在不同的目录中分发本地二进制文件,所以它看起来像这样:

    • \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 包安装可能会让您最轻松地开始。

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

    【讨论】:

    • 注意,我必须在我正在处理的 .NET 目标的二进制 zip 文件中找到互操作 DLL。
    【解决方案2】:

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

    • 下载库的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 与 x64)库,而无需在 GAC 或类似中注册任何内容。

    希望这会有所帮助。

    【讨论】:

    • 我应该在 bin 文件夹中添加哪个 System.Data.SQLite.dll,x32 或 x64 可用的 dll?我下载了 x32 和 x64,每个版本都有 System.Data.SQLite.dll,它们的大小不同....
    • 嗯,它们应该有相同的大小,你下载了哪些版本?
    • 没错,两个库是一样的,我用文件比较器查过了,要下载this for x86this for x64
    • 为什么这是公认的答案?将库扔到系统文件夹中,真的吗?这将使部署成为一场噩梦。
    • 我赞同@Odys 所说的——这不是这样做的方法。将库放到 GAC 中会起作用,但只能在您的一台机器上使用。对于安装它的任何其他人,您的程序仍然会被破坏。
    【解决方案3】:

    不,没有。

    这是因为这些 *.dll 只是原生 c/c++ *.dll 的包装器。 而 32 位的 .NET 应用程序必须使用 32 位的 c/c++ dll,而 64 位的 .NET 应用程序必须使用 64 位的 c/c++ dll。

    好久没用vb.net了,不知道能不能像c#一样配置目标平台。如果可以,您应该这样做并使用正确的互操作 dll。你应该决定是需要 32 位还是 64 位。

    【讨论】:

    • 那么我需要编译两次,一次是32,另一次是64?
    • 是的,如果您想提供 32 位和 64 位版本。因为如果您将目标设置为“任何 cpu”,它将编译为目标版本(64 或 32 取决于目标窗口)。您必须将目标设置为 x86(32 位)或 x64(64 位)。
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      使用Nuget 可以轻松解决问题的最新状态 安装后搜索SQLitelike:

      PM> Install-Package System.Data.SQLite 
      

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

      【讨论】:

      • 这仍然为您提供两个 DLL。 OP 想知道如何只使用其中一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 2010-12-19
      • 2023-04-10
      • 1970-01-01
      • 2011-11-29
      相关资源
      最近更新 更多