6

Scintilla.Net コンポーネントを介してマネージド アプリケーションから読み込まれるアンマネージド DLL (Scintilla コード エディターの scilexer.dll、CodePlexの Scintilla.Net によって使用される) があります。Windows 管理アプリケーションは、32 ビット環境と 64 ビット環境の両方で問題なく実行されますが、64 ビットまたは 32 ビットの scilexer.dll を使用する別のインストールを作成する必要があります。

32 ビット形式と 64 ビット形式の両方の DLL を配布する方法はありますか?

4

5 に答える 5

5

P/Invoke は LoadLibrary を使用して DLL を読み込みます。指定された名前で読み込まれたライブラリが既に存在する場合、LoadLibrary はそれを返します。したがって、両方のバージョンの DLL に同じ名前を付けて、それらを異なるディレクトリに置くことができる場合、extern 宣言を複製する必要なく、scilexer.dll からの関数への最初の呼び出しの前に、次のようなことを 1 回だけ行うことができます。

    string platform = IntPtr.Size == 4 ? "x86" : "x64";
    string dll = installDir + @"\lib-" + platform + @"\scilexer.dll";
    if (LoadLibrary(dll) == IntPtr.Zero)
        throw new IOException("Unable to load " + dll + ".");
于 2009-03-17T02:31:56.253 に答える
4

残念ながら、私はこの特定の DLL について何も知りません。ただし、P/Invoke を自分で実行し、多少の重複に対処できる場合は、プラットフォームごとに 1 つのプロキシを作成することができます。

たとえば、32 ビットまたは 64 ビットの DLL で実装する必要がある次のインターフェイスがあるとします。

public interface ICodec {
    int Decode(IntPtr input, IntPtr output, long inputLength);
}

プロキシを作成します。

public class CodecX86 : ICodec {
    private const string dllFileName = @"Codec.x86.dll";

    [DllImport(dllFileName)]
    static extern int decode(IntPtr input, IntPtr output, long inputLength);

    public int Decode(IntPtr input, IntPtr output, long inputLength) {
        return decode(input, output, inputLength);
    }
}

public class CodecX64 : ICodec {
    private const string dllFileName = @"Codec.x64.dll";

    [DllImport(dllFileName)]
    static extern int decode(IntPtr input, IntPtr output, long inputLength);

    public int Decode(IntPtr input, IntPtr output, long inputLength) {
        return decode(input, output, inputLength);
    }
}

最後に、適切なものを選択するファクトリを作成します。

public class CodecFactory {
    ICodec instance = null;

    public ICodec GetCodec() {
        if (instance == null) {
            if (IntPtr.Size == 4) {
                instance = new CodecX86();
            } else if (IntPtr.Size == 8) {
                instance = new CodecX64();
            } else {
                throw new NotSupportedException("Unknown platform");
            }
        }
        return instance;
    }
}

DLL は最初に呼び出されたときに遅延ロードされるため、各プラットフォームがネイティブのバージョンしかロードできないにもかかわらず、これは実際に機能します。詳細な説明については、この記事を参照してください。

于 2009-01-31T17:18:00.673 に答える
2

私が思いついた最高のものは次のとおりです。

  • 64または32という名前の2つのDLLを使用してアプリケーションを配布します
  • メインのスタートアップコードには、次のものが含まれます。
    
    File.Delete(Application.StartupPath + @ "\ scilexer.dll");
    {{
      // 64ビットを確認し、適切なscilexerdllをコピーします
        if(IntPtr.Size == 4)
        {{
          File.Copy(Application.StartupPath + @ "\ scilexer32.dll"、
            Application.StartupPath + @ "\ scilexer.dll");
        }
        そうしないと
        {{
          File.Copy(Application.StartupPath + @ "\ scilexer64.dll"、
            Application.StartupPath + @ "\ scilexer.dll");
        }
    }
于 2008-12-18T11:43:36.910 に答える
1

dllをsystem32に入れることができます。syswow64 では 32 ビット、実際のシステムでは 64 ビットです32。32 ビット アプリケーションの場合、system32 にアクセスすると、Syswow64 にリダイレクトされます。

レジストリにエントリを作成できます。ソフトウェア キーには Wow6432Node という名前のサブキーがあり、32 ビット アプリケーションはこれをソフトウェア キーとして認識します。

これがpowershellインストーラーの機能です。

于 2008-12-18T08:25:25.813 に答える
0

アンマネージド dll は、対応するマネージド DLL と並行して GAC にインストールできます。 この記事では、それがどのように機能するかを説明する必要があります。

于 2008-12-18T15:39:15.283 に答える