tags:

views:

589

answers:

2

I'm working on a code (WinForms C# NET 3.5) that involves using unrar.

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

Since i want the code to be working on both 32BIT and 64BIT i wanted to assign UNRAR64.DLL or UNRAR.DLL via a string unrarDll depending on check for bitness 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);
    }

Error is thrown:

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

IS there easy way around this? What would be the proper way of doing this?

+6  A: 

no :-) it's a part of the spec ... you'll have to have two separate builds for each platform (x86/x64). What you can do is simply define a preprocessor directive, and then do something like

#if x64
// ... define all x64 imports here
#else
// ... define all x86 imports here
#endif
Joel Martinez
It works fine for 7zip, just unrar doesn't allow to be set the way 7zip does.
MadBoy
As an aside, the DllImport does come close to enabling this, with the CharSet field, in which it will correctly call the A or W version of an API method depending on whether its an ASCII or Unicode system - but those methods have to be in the same DLL. Too bad it can't do something similar across different DLL's.
Nick
+4  A: 

Create an interface for the unrar imports and implement 32 bit and 64 bits versions separately. If 32 bit, instantiate the 32 bit impl, else instantiate the 64 bit impl.

gilbertc
This is my favorate option. It's easy to have two versions of the interface, plus, you get a nice, managed interface to work with this way...
Reed Copsey
Can you show an example how it could look like?
MadBoy