Um argumento de atributo deve ser uma expressão constante, existe uma maneira de contornar isso em C#?

StackOverflow https://stackoverflow.com/questions/2321103

  •  22-09-2019
  •  | 
  •  

Pergunta

Estou trabalhando em um código (Winforms C# Net 3.5) que envolve o uso do UNRRAR.

    [DllImport("UNRAR64.DLL")]
    private static extern IntPtr RAROpenArchive(ref RAROpenArchiveData archiveData);
    [DllImport("UNRAR64.DLL")]
    private static extern IntPtr RAROpenArchiveEx(ref RAROpenArchiveDataEx archiveData);
    [DllImport("UNRAR64.DLL")]
    private static extern int RARCloseArchive(IntPtr hArcData);
    [DllImport("UNRAR64.DLL")]
    private static extern int RARReadHeader(IntPtr hArcData, ref RARHeaderData headerData);
    [DllImport("UNRAR64.DLL")]
    private static extern int RARReadHeaderEx(IntPtr hArcData, ref RARHeaderDataEx headerData);
    [DllImport("UNRAR64.DLL")]
    private static extern int RARProcessFile(IntPtr hArcData, int operation, [MarshalAs(UnmanagedType.LPStr)] string destPath, [MarshalAs(UnmanagedType.LPStr)] string destName);
    [DllImport("UNRAR64.DLL")]
    private static extern void RARSetCallback(IntPtr hArcData, UNRARCallback callback, int userData);
    [DllImport("UNRAR64.DLL")]
    private static extern void RARSetPassword(IntPtr hArcData, [MarshalAs(UnmanagedType.LPStr)] string password);

Como eu quero que o código esteja trabalhando em 32 bits e 64 bits, eu queria atribuir UNRRAR64.DLL ou UNRRAR.DLL por meio de uma string não dependendo da verificação do Bitsness of System.

    private void DllChoice() {
        if (SystemIs64Bit()) {
            sevenZipDll = "7z-x64.dll";
            unrarDll = "unrar.dll";
        } else {
            sevenZipDll = "7x-x32.dll";
            unrarDll = "unrar64.dll";
        }
    } 
    private static bool SystemIs64Bit() {
        return (IntPtr.Size == 8);
    }

O erro é lançado:

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

Existe uma maneira fácil de contornar isso? Qual seria a maneira correta de fazer isso?

Foi útil?

Solução

Não :-) É uma parte da especificação ... você terá que ter duas construções separadas para cada plataforma (x86/x64). O que você pode fazer é simplesmente definir uma diretiva de pré -processador e depois fazer algo como

#if x64
// ... define all x64 imports here
#else
// ... define all x86 imports here
#endif

Outras dicas

Crie uma interface para as importações UNRAR e implemente versões de 32 e 64 bits separadamente. Se 32 bits, instancie o Impl de 32 bits, caso contrário, instanciam o implic em 64 bits.

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