Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: One attribute for multiple declarations (DLLImport)

I'm using the [DLLImport] attribute to access a bunch of C++ functions in my .NET code. For now, I have all the functions in the following way:

const string DLL_Path = "path\\to\\my\\dll.dll";

[DllImport(DLL_Path, 
    CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi)] 
public static extern int MyFunction1();

[DllImport(DLL_Path, 
    CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction2(int id);

[DllImport(DLL_Path, 
    CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction3(string server, byte timeout, 
    ref int connection_id, ref DeviceInfo pInfos);

[DllImport(DLL_Path, 
    CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction4([MarshalAs(UnmanagedType.LPArray)] byte[] pVersion, 
    ref int psize);

[DllImport(DLL_Path, 
    CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction5(int errorcode, 
    [MarshalAs(UnmanagedType.LPTStr)] string pmsg, ref int psize);

Which is rather not pleasing to the eye: the repetition of attributes seems unefficient and destroys readability for the prototypes of the functions. Especially since I have something like 20 or 30 functions to import.

I wonder if I could have the [DllImport(DLL_Path, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] part only once somewhere and have the function definitions more clearly identified, like this pseudo code:

const string DLL_Path = "path\\to\\my\\dll.dll";
// some code defining a section which tells that the next functions are DLLImport
[DllImport(DLL_Path, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
{
    public static extern int MyFunction1();

    public static extern ErrorCode MyFunction2(int id);

    public static extern ErrorCode MyFunction3(string server, byte timeout, ref int connection_id, ref DeviceInfo pInfos);

    public static extern ErrorCode MyFunction4([MarshalAs(UnmanagedType.LPArray)] byte[] pVersion, ref int psize);

    public static extern ErrorCode MyFunction5(int errorcode, [MarshalAs(UnmanagedType.LPTStr)] string pmsg, ref int psize);
}

Is this possible?
I found this question in SO: Shorten amount of DllImport in C#? but it suggests dynamically loading the functions through LoadLibrary and GetProcAddress, which I find less readable.

like image 303
Gui13 Avatar asked Apr 03 '13 07:04

Gui13


1 Answers

No, there's no way to reduce the Attributes to a single declaration. You'll need to apply the Attribute to all methods.

But you can at least shorten your Attribute declarations to [DllImport(DLL_Path)], because the values you are specifying for CallingConvention and CharSet are the same as the default values.

like image 138
Botz3000 Avatar answered Nov 04 '22 05:11

Botz3000