簡體   English   中英

在32位和64位C#世界中使用System.Data.SQLite的選項

[英]Options for using System.Data.SQLite in a 32bit and 64bit C# world

我理解為什么在32位和64位版本中提供System.Data.SQLite.dll。 所以我們不要再糾纏於此並繼續前進。 :)

由於它以這種方式完成,它似乎使得純粹的C#開發更難以做出3個選擇。

  1. 是僅支持32位並強制使用托管程序集來編譯x86並在32或64位運行時處理它,並且當你在64位環境中時會失去優勢。

  2. 是強制64位並且僅支持64位並且失去了在32位上運行的能力但是獲得了64位的所有優點。

  3. 是創建兩個版本的程序集,一個編譯x86並使用32位SQLite,另一個編譯x64並使用64位SQLite。 它阻止使用“ANY”作為編譯選項,並且能夠輕松地將單個構建部署到任一類型。 從開發的角度來管理並不是那么可怕,因為我們需要兩個項目。 只將C#代碼正式放在一個,而另一個只使用“鏈接”到另一個代碼。 這僅用於編譯目的。 仍然讓我們必須管理兩個輸出以進行部署。

盡管如此,我只是在尋找確認以上是唯一正確的選擇。

如果我還有其他選擇,請告訴我。 具體來說,如果有方法可以獲得一個可以編譯為ANY的單個C#DLL,那么它可以利用32位或64位,具體取決於它的運行位置並仍然使用System.Data.SQLite.dll。

這是Springy76答案的詳細說明。 做這個:

public class AssemblyResolver
{
    public static void HandleUnresovledAssemblies()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += currentDomain_AssemblyResolve;
    }

    private static Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (args.Name == "System.Data.SQLite")
        {
            var path = Path.Combine(pathToWhereYourNativeFolderLives, "Native");

            if (IntPtr.Size == 8) // or for .NET4 use Environment.Is64BitProcess
            {
                path = Path.Combine(path, "64");
            }
            else
            {
                path = Path.Combine(path, "32");
            }

            path = Path.Combine(path, "System.Data.SQLite.DLL");

            Assembly assembly = Assembly.LoadFrom(path);
            return assembly;
        }

        return null;
    }
}

確保生成的路徑指向32位或64位SQLite Dll的正確位置。 就個人而言,我在這個NuGet包中獲得了很好的結果: http ://www.nuget.org/packages/SQLitex64

(您只需要使用NuGet包來獲取已編譯的SQLite Dll。一旦獲得它們,刪除由NuGet和NuGet包本身創建的項目中對SQLite的引用。實際上,保留引用可以干擾此解決方案,因為SQLite永遠不會被識別為未解決的程序集。)

盡可能早地調用'HandleUnresolvedAssemblies()',最好是在任何Bootstrapping期間。

將您的主要應用程序保存在AnyCPU有兩種常用的解決方案:

  • 將x86和x64程序集安裝到GAC中:它們可以(應該!)具有相同的程序集名稱,GAC將自動決定是使用x86還是x64版本。

  • 使用Assembly.LoadFrom掛鈎到AppDomain.AssemblyResolve並從子目錄提供正確的程序集

Oracle的ODP.NET與本機32/64位OCI DLL相似也存在類似的問題。

我們通過為我們的項目創建'x86'和'x64'平台來解決它,然后手動編輯我們的項目文件以使用條件引用:

<Choose>
<When Condition="'$(Platform)' == 'x64'">
  <ItemGroup>
    <Reference Include="Oracle.DataAccess, processorArchitecture=x64">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\ThirdParty\ODP.NET\x64\Oracle.DataAccess.dll</HintPath>
    </Reference>
    <Content Include="..\ThirdParty\ODP.NET\x64\oci.dll">
      <Link>oci.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x64\orannzsbb11.dll">
      <Link>orannzsbb11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x64\oraociei11.dll">
      <Link>oraociei11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x64\OraOps11w.dll">
      <Link>OraOps11w.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
</When>
<When Condition="'$(Platform)' == 'x86'">
  <ItemGroup>
    <Reference Include="Oracle.DataAccess, processorArchitecture=x86">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\ThirdParty\ODP.NET\x86\Oracle.DataAccess.dll</HintPath>
    </Reference>
    <Content Include="..\ThirdParty\ODP.NET\x86\oci.dll">
      <Link>oci.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x86\orannzsbb11.dll">
      <Link>orannzsbb11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x86\oraociei11.dll">
      <Link>oraociei11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x86\OraOps11w.dll">
      <Link>OraOps11w.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
</When>
</Choose>

這使我們能夠避免使用2個不同的項目。 我相信你可以為SQLite做類似的事情。

從開發的角度來管理並不是那么可怕,因為我們需要兩個項目。

事實並非如此 - 您可以在同一個項目中使用兩個構建配置。 在部署時,您需要為x86和x64構建,但代碼庫和項目可以是相同的。

我目前在一個更大的生產項目中執行此操作,這既包括SQLite,也包括其他包含x64和x86變體的本機/互操作庫。

Branko Dimitrijevic說:“我相信你可以為SQLite做類似的事情。” 這是正確的。 :)

遇到同樣的問題,我找到了羅德尼的問題和布蘭科的答案,並親自嘗試過。 對於任何想要查看我的SQLite實現的人,請轉到:

<Choose>
  <When Condition="'$(Platform)' == 'x64'">
    <ItemGroup>
      <Reference Include="System.Data.SQLite, Version=1.0.88.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
        <SpecificVersion>False</SpecificVersion>
        <HintPath>System.Data.SQLite\x64\System.Data.SQLite.dll</HintPath>
      </Reference>
    </ItemGroup>
  </When>
  <When Condition="'$(Platform)' == 'x86'">
    <ItemGroup>
      <Reference Include="System.Data.SQLite, Version=1.0.88.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
        <SpecificVersion>False</SpecificVersion>
        <HintPath>System.Data.SQLite\x86\System.Data.SQLite.dll</HintPath>
      </Reference>
    </ItemGroup>
  </When>
</Choose>

<ItemGroup>
  <Reference Include="Microsoft.CSharp" />
  <Reference Include="System" />
  <Reference Include="System.configuration" />
  <Reference Include="System.Core" />
  <Reference Include="System.Windows.Forms" />
  <Reference Include="System.Xml.Linq" />
  <Reference Include="System.Data.DataSetExtensions" />
  <Reference Include="System.Data" />
  <Reference Include="System.Xml" />
</ItemGroup>

當然,您可以將HintPath命名為您喜歡的任何名稱。

我發現這是一個完美的解決方案:我可以維護一個項目,並根據需要在目標平台之間快速切換。 唯一可能的缺點是我無法在解決方案資源管理器中看到參考。 但這是為整體功能付出的小代價。

除非您的應用程序需要超過4GB的內存,否則通常選擇一種方法。 請記住,64位操作系統上的32位應用程序具有64位的大部分優點,沒有許多缺點。 這就是為什么x86是VS 2010中.exe應用程序的默認目標。

您還可以通過更改Visual Studio中的編譯選項來解決此問題:

要在Visual Studio中更改編譯設置:

  1. 轉到程序的啟動項目。
  2. 打開屬性窗口。
  3. 單擊編譯選項卡。
  4. 單擊高級編譯選項。
  5. 將目標CPU選項更改為x86。

您的程序現在將始終以32位模式運行,即使在64位計算機上運行也是如此。

您還可以提供兩個分發,一個針對上面提到的每個環境。 雖然這將成為未來的標准,但對於我目前的項目來說,這是最好和最簡單的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM