簡體   English   中英

基於64位或32位操作系統導入外部DLL

[英]Import external dll based on 64bit or 32bit OS

我有一個32位和64位版本的dll。 我的.NET WinForm配置為“任何CPU”,我的老板不會讓我們為不同的操作系統版本單獨安裝。 所以我想知道:如果我在安裝中打包兩個dll,那么有沒有辦法讓WinForm確定它的64位/ 32位並加載正確的dll。

我發現這篇文章用於確定版本。 但我不知道如何注入正確的方法來定義我想要使用的方法的DLLImport屬性。 有任何想法嗎?

您可以利用SetDllDirectory API函數,它會改變非托管程序集的搜索路徑。 將32位DLL存儲在app安裝目錄的x86子目錄中,即x64子目錄中的64位DLL。

在進行任何P / Invoke之前,在app啟動時運行此代碼:

using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
...

    public static void SetUnmanagedDllDirectory() {
        string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        path = Path.Combine(path, IntPtr.Size == 8 ? "x64 " : "x86");
        if (!SetDllDirectory(path)) throw new System.ComponentModel.Win32Exception();
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool SetDllDirectory(string path);

你可以導入它們並決定通過.NET調用哪一個?

例如:

[DllImport("32bit.dll", CharSet = CharSet.Unicode, EntryPoint="CallMe")]
public static extern int CallMe32 (IntPtr hWnd, String text, String caption, uint type);

[DllImport("64bit.dll", CharSet = CharSet.Unicode, EntryPoint="CallMe")]
public static extern int CallMe64 (IntPtr hWnd, String text, String caption, uint type);

您應該創建兩個不同的私有extern方法,並創建一個內部方法來檢查IntPtr.Size並調用正確的版本。

我的解決方案是創建一個抽象類,具有加載和包裝我的32位DLL的具體版本,以及一個加載和包裝64位DLL的單獨實現。 基類中的單個工廠方法可用於基於IntPtr.Size實例化適當的實現。

這種方法的好處是你的代碼的其余部分完全與平台隔離 - 它只是使用你的基類工廠方法構造一個對象,並使用它。 也可以很容易地以統一的方式調用DLL中的多個方法,並且可以輕松地將所有“本機”代碼推送到私有實現中。

...或者您可以使用Marshal.GetDelegateForFunctionPointer()來執行動態P / Invoke
...或者在CLR嘗試為您加載之前,使用完全限定的路徑調用LoadLibrary()

暫無
暫無

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

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