C# 用于 x86/x64 架构的 SQLite dll

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18163354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:26:29  来源:igfitidea点击:

SQLite dll for x86/x64 architectures

c#vb.netdllsqlite

提问by cMinor

I am developing a program in VB.net, and using System.Data.SQLitePrecompiled Binaries for .NET, However It is not working for x64 Architectures, and I am getting the classic culture problem and not loading correct file.

我正在 VB.net 中开发一个程序,并使用System.Data.SQLitePrecompiled Binaries for .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'

Is there a way to use only one dll, maybe:

有没有办法只使用一个 dll,也许:

  1. Add some directives like #IFDEF(x86 include some part of code) or else x64 code
  2. Join dlls to make only one.
  3. Reference this dll in VB.net
  1. 添加一些指令,如#IFDEF(x86 包含部分代码)或其他 x64 代码
  2. 加入 dll 只制作一个。
  3. 在 VB.net 中引用这个 dll

Do you think is other better Idea, as I would like to make only one compilation, not one for x32 and other for x64.

你认为还有其他更好的想法吗,因为我只想做一个编译,而不是一个用于 x32 和另一个用于 x64。

For instance (32 bits):

例如(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

How to change that to work on 64 bit architecture? Maybe including both 32 and 64 dll's and in functions do something like

如何更改它以在 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

采纳答案by Govert

There are various options for using SQLite from a .NET assembly. Your first step is to move to something newer than the ancient 1.0.65 version. Current versions can be downloaded from here: http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wikior via the SQLite NuGet packages.

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

If you need to be able to run under both 32-bit and 64-bit, one option is to use the native library pre-loadingoption, where you distribute the native binaries in separate directories, so that it looks like this:

如果您需要能够在 32 位和 64 位下运行,一种选择是使用本机库预加载选项,您可以在单独的目录中分发本机二进制文件,使其看起来像这样:

  • \App.exe (optional, managed-only application executable assembly)
  • \App.dll (optional, managed-only application library assembly)
  • \System.Data.SQLite.dll (required, managed-only core assembly)
  • \System.Data.SQLite.Linq.dll (optional, managed-only LINQ assembly)
  • \x86\SQLite.Interop.dll (required, x86 native interop assembly)
  • \x64\SQLite.Interop.dll (required, x64 native interop assembly)
  • \App.exe(可选的、仅托管的应用程序可执行程序集)
  • \App.dll(可选的、仅托管的应用程序库程序集)
  • \System.Data.SQLite.dll(必需的,仅限托管的核心程序集)
  • \System.Data.SQLite.Linq.dll(可选的,仅限托管的 LINQ 程序集)
  • \x86\SQLite.Interop.dll(必需,x86 本机互操作程序集)
  • \x64\SQLite.Interop.dll(必需,x64 本机互操作程序集)

Another option is to build two versions of your app, and in each version you reference the appropriate mixed-mode assembly. You'd then end up with two versions, but they're a bit simpler to deal with since you don't need the extra subdirectory and native *.Interop.dlls.

另一种选择是构建应用程序的两个版本,并在每个版本中引用适当的混合模式程序集。然后您会得到两个版本,但它们处理起来更简单一些,因为您不需要额外的子目录和本机 *.Interop.dll。

In these cases you'd need no code differences or optional compilation between 32-bit and 64-bit. Installing from the different NuGet packages will probably get you started most easily.

在这些情况下,您不需要 32 位和 64 位之间的代码差异或可选编译。从不同的 NuGet 包安装可能会让你最容易上手。

A final option is to go for the managed-only clone called C#-SQLite: https://code.google.com/p/csharp-sqlite/. It's a port of the SQLite engine to managed C#, so the whole thing runs as AnyCPU and the bitness is not an issue.

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

回答by user743414

No there isn't one.

不,没有。

That's because these *.dlls are just wrappers for native c/c++ *.dll's. And a 32 bit, .NET application have to use the 32 bit c/c++ dll and a 64 bit, .NET application have to use the 64 bit c/c++ dll.

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

I haven't used vb.net for a long time, I'm not sure if you can configure the target platform like you can do in c#. If you can, you should do so and take the right interop dll. And you should decide if you need 32 bit or 64 bit.

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

回答by Tobia Zambon

I had the same problem few year ago and for me the best solution is:

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

  • download the latest versionof the library
  • in your bin path put only the System.Data.SQLite.dlland eventually System.Data.SQLite.Linq.dll
  • put the x86 SQLite.Interop.dlllibrary into c:\Windows\SysWOW64
  • put the x64 SQLite.Interop.dlllibrary into c:\Windows\System32
  • compile your project as Any CPUreferencing only System.Data.SQLite(the dll into your bin path)
  • enjoy
  • 下载最新版本的库
  • 在你的 bin 路径中只放System.Data.SQLite.dll和最终System.Data.SQLite.Linq.dll
  • 将 x86SQLite.Interop.dll库放入c:\Windows\SysWOW64
  • 将 x64SQLite.Interop.dll库放入c:\Windows\System32
  • 将您的项目编译为Any CPU仅引用System.Data.SQLite(将 dll 放入您的 bin 路径)
  • 请享用

In this way the .NET framework will automatically load the correct (x86 vs x64) library during the runtime without registering anything in GAC or similar.

通过这种方式,.NET 框架将在运行时自动加载正确的(x86 与 x64)库,而无需在 GAC 或类似内容中注册任何内容。

Hope this helps.

希望这可以帮助。

回答by Rory

The other answers here by @Govert and @TobiaZambon are the right way to go. But for anyone else reading, another option is to use the x86 version of the System.Data.Sqlite dll and only compile your application for x86 platform. i.e. don't compile to AnyCPU, which means when it runs on x64 machine windows will run it in 32-bit mode and it'll be able to load the 32-bit dll.

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

Whether this is useful will depend on your situation, but if you're building an app that's deployed to workstations it's quite a simple solution.

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

回答by cMinor

The state of art of the question can easily be solved using NugetAfter install it, search SQLitelike:

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

PM> Install-Package System.Data.SQLite 

I have done this using a brand new computer and VS, I needed SQLite and did this and everything worked fine.

我使用全新的计算机和 VS 完成了此操作,我需要 SQLite 并执行此操作,并且一切正常。