【问题标题】:Refactoring many identical DllImport declarations重构许多相同的 DllImport 声明
【发布时间】:2011-01-24 06:34:46
【问题描述】:

我有一个包含本地 DLL 接口的模块;它看起来像这样:

// nvtt.dll binding module
module private NvTextureTools =
    type NvttInputOptions = IntPtr

    [<DllImport("nvtt", CallingConvention = CallingConvention.Cdecl)>]
    extern NvttInputOptions nvttCreateInputOptions()

    [<DllImport("nvtt", CallingConvention = CallingConvention.Cdecl)>]
    extern void nvttDestroyInputOptions(NvttInputOptions)

    [<DllImport("nvtt", CallingConvention = CallingConvention.Cdecl)>]
    extern void nvttSetInputOptionsAlphaMode(NvttInputOptions, AlphaMode alphaMode)

    [<DllImport("nvtt", CallingConvention = CallingConvention.Cdecl)>]
    extern void nvttSetInputOptionsGamma(NvttInputOptions, float inputGamma, float outputGamma)

    [<DllImport("nvtt", CallingConvention = CallingConvention.Cdecl)>]
    extern void nvttSetInputOptionsWrapMode(NvttInputOptions, WrapMode mode)

(有 5 倍以上的功能,但这应该给出大致的概念)。

有没有办法只指定一次 DllImport 参数?据我了解,我不能从 DllImport 继承(它是密封的,无论如何我认为如果不是它就行不通),我不能使用反射来添加必要的属性,因为我需要它们编译时间。

我可以使用反射创建一个带有 P/Invoke 方法的全新类,但这会使调用它们变得很麻烦。

有什么想法吗?

【问题讨论】:

    标签: f# pinvoke dllimport


    【解决方案1】:

    我不知道 F#,但在 C# 中你可以执行以下操作:

    static const string DllName = "nvtt";
    
    [DllImport(DllName, other params...)]
    some function signature
    
    [DllImport(DllName, other params...)=
    some function signature
    

    这样,实际的字符串只声明一次——DllImport 属性本身看起来仍然很相似,但它使更改变得更容易。我认为您可以对 CallingConvention 做同样的事情,但我从未尝试过使用枚举。

    【讨论】:

    • FWIW,等效的 F# 将是:[&lt;Literal&gt;] let DllName = "nvtt"
    • 这与 [] 评论并不能完全解决我的问题 :) 但它教会了我文字语法,所以我接受这个评论 - 没有其他方法不使用外部无论如何都是工具。
    【解决方案2】:

    以防万一您使用的是 Visual Studio - 可以创建 T4 模板并生成所有这些讨厌的属性。这不是 F# 或 VS 特定的解决方案,但是,任何代码生成工具都可以工作。

    【讨论】:

      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      相关资源
      最近更新 更多