Pergunta

Eu tenho uma DLL não gerenciada (o scilexer.dll de editor de código Scintilla, usado por Scintilla.Net de CodePlex ) que é carregado a partir de uma aplicação de gestão calha do componente Scintilla.Net. As janelas conseguiu aplicativo é executado sem problemas em ambos os ambientes de 32 e 64 bits, mas eu preciso para criar instalações diferentes que usa o 64 ou o 32 scilexer.dll.

Existe uma maneira de distribuir os dois DLLs em 32 e formato de 64 bit para que o carregador DLL das cargas do .NET Framework a DLL não gerenciada no formato de 32 ou 64 bits, dependendo alguma opção config ou algum "nome mágico caminho "coisas?

Foi útil?

Solução

P / Invoke usa LoadLibrary para DLLs de carga, e se já existe uma biblioteca carregado com um determinado nome, LoadLibrary irá devolvê-lo. Então, se você pode dar a ambas as versões da DLL o mesmo nome, mas colocá-los em diretórios diferentes, você pode fazer algo como isto apenas uma vez antes de sua primeira chamada para uma função de scilexer.dll, sem a necessidade de duplicar os seus declarações extern:

    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 + ".");

Outras dicas

Infelizmente, eu não sei nada sobre esse DLL particular. No entanto, quando você faz o P / Invoke si mesmo, e você pode lidar com um pouco de duplicação, é possível criar um proxy para cada plataforma.

Por exemplo, suponha que você tenha o seguinte interface, que deve ser executada até uma DLL de 32 ou 64 bits:

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

Você cria os proxies:

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);
    }
}

e

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);
    }
}

E, finalmente, fazer uma fábrica que escolhe o caminho certo para você:

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;
    }
}

Como as DLLs são carregados preguiçosamente a primeira vez que eles estão sendo invocado, isso realmente funciona, apesar de cada plataforma apenas ser capaz de carregar a versão que é nativo a ele. Consulte este artigo para uma explicação mais detalhada.

O melhor que eu vim acima com é o seguinte:

  • Distribuir a minha candidatura com duas DLLs nomeados 64 ou 32
  • No código de inicialização principal incluem o seguinte:
    
    File.Delete(Application.StartupPath + @"\scilexer.dll");
    {
      // Check for 64 bit and copy the proper scilexer dll
        if (IntPtr.Size == 4)
        {
          File.Copy(Application.StartupPath + @"\scilexer32.dll",
            Application.StartupPath + @"\scilexer.dll");
        }
        else
        {
          File.Copy(Application.StartupPath + @"\scilexer64.dll",
            Application.StartupPath + @"\scilexer.dll");
        }
    }

Você pode colocar a dll no system32. A 32 bit em syswow64 e 64 bits no system32 real. Para 32 aplicativo bit, quando thay acesso System32 eles são redirecionados para Syswow64.

Você pode criar uma entrada no registro. A chave software tem uma subchave denominada Wow6432Node que a aplicação de 32 bits ver como a chave de software.

Aqui está o que instalador PowerShell faz .

DLLs não gerenciados podem ser instalados no GAC lado-a-lado com os seus homólogos gerenciados. Este artigo deve explicar como ele funciona.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top