Um argumento de atributo deve ser uma expressão constante, existe uma maneira de contornar isso em C#?
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?
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.