C#:一个属性用于多个声明 (DLLImport)

Posted

技术标签:

【中文标题】C#:一个属性用于多个声明 (DLLImport)【英文标题】:C#: One attribute for multiple declarations (DLLImport) 【发布时间】:2013-04-03 07:44:51 【问题描述】:

我正在使用[DLLImport] 属性来访问我的.NET 代码中的一堆C++ 函数。 目前,我通过以下方式拥有所有功能:

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

这很不讨人喜欢:属性的重复似乎效率低下,并且破坏了函数原型的可读性。特别是因为我有 20 或 30 个函数要导入。

我想知道我是否可以在某个地方只使用一次 [DllImport(DLL_Path, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 部分并且更清楚地识别函数定义,例如这个伪代码:

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

这可能吗? 我在 SO:Shorten amount of DllImport in C#? 中发现了这个问题,但它建议通过 LoadLibraryGetProcAddress 动态加载函数,我觉得这不太可读。

【问题讨论】:

答案是否定的,坚持现有的,顺眼与否。 这家伙太卑鄙了!你不想有时改变事情的顺序吗?还是你坚持现有的东西,并且从未梦想过一个导入 DLL 函数更容易、更漂亮的世界? 【参考方案1】:

不,没有办法将属性简化为单个声明。您需要将 Attribute 应用于所有方法。

但是您至少可以将属性声明缩短为[DllImport(DLL_Path)],因为您为CallingConventionCharSet 指定的值与默认值相同。

【讨论】:

这对我来说已经足够好了,我会把它们放在声明的前面,这样更容易阅读。我错过了一个“属性范围”......这将是一个很好的补充!

以上是关于C#:一个属性用于多个声明 (DLLImport)的主要内容,如果未能解决你的问题,请参考以下文章

C# 中用于从 DllImport 函数中检索引用的指针

C#中DllImport是啥意思啊

用C# 做一个读取身份证阅读程序

C#调用C/C++的dll,一个库中包括多个函数,每调用一个函数都要用DllImport加载吗?求大神

参数化 DllImport 以在 C# 应用程序中使用

DllImport 与 VB.NET 中的声明