为什么 F# 编译器对一种情况给出错误,而对另一种情况则不给出错误?

2024-03-08

我正在处理来自 F# 的平台调用,并且收到一个编译器错误,我真的无法理解。首先,让我展示一下我正在做的事情的 C 签名:

int Foo(
    ULONG_PTR *phHandle,
    DWORD flags
);

在 F# 中,我认为本地调用它的正确方法如下:

[<DllImport("somedll.dll")>]
static extern int APlatformInvokeCall
    (
        [<Out>]nativeint& phHandle,
        uint32 flags
    )

如果我尝试调用这个在课堂上,像这样调用它时出现编译错误:

type Class1() = 
    [<DllImport("somedll.dll")>]
    static extern int APlatformInvokeCall
        (
            nativeint& phHandle,
            uint32 flags
        )

    member this.Foo() =
        let mutable thing = nativeint 0
        APlatformInvokeCall(&thing, 0u) |> ignore
        thing

错误是:

类型实例化涉及 byref 类型。 Common IL 规则不允许这样做。

奇怪的是,当我在模块中完成这一切时,编译错误就消失了:

module Module1 = 
    [<DllImport("somedll.dll")>]
    extern int APlatformInvokeCall
        (
            nativeint& phHandle,
            uint32 flags
        )

    let Foo() =
        let mutable thing = nativeint 0
        APlatformInvokeCall(&thing, 0u) |> ignore
        thing

为什么它编译为模块,而不是类?


我认为定义一个是无效的externF# 中类中的方法。

如果你拉起F# 3.0 语言规范 http://fsharp.org/about/并搜索DllImport,靠近底部的是一个表格,列出了一些特殊属性以及如何使用它们。文本为[<DllImport>] says:

当应用于模块中的函数定义时,导致 F# 编译器忽略定义的实现,而是将其编译为 CLI P/Invoke 存根声明。

这似乎表明只有声明才有效extern方法(使用[<DllImport>]) 模块中定义的函数;但它没有提及任何有关班级成员的信息。

我认为您遇到了编译器错误。请将此代码提交至[email protected] /cdn-cgi/l/email-protection这样他们就可以修复编译器发出的错误消息——它实际上应该给你一个关于定义extern类中的方法,因为语言规范不允许这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 F# 编译器对一种情况给出错误,而对另一种情况则不给出错误? 的相关文章

  • 在活动模式中使用 typeof<_>

    给出以下人为的活动模式 let TypeDef typeDef Type value obj if obj ReferenceEquals value null then None else let typ value GetType if
  • F# 中的部分匿名记录

    我如何输入一个函数 该函数接受具有字段的记录a and 任何其他领域 与此等效吗标准机器学习F 中可以使用函数吗 fun f a string Hello a 尝试了以下内容 但这些似乎在语法上无效 let f r a string imp
  • F# 中的非类型化/类型化代码引用与宏卫生之间是否存在关系?

    我想知道 F 中的非类型 类型代码引用与宏系统的卫生之间是否存在关系 他们是否用各自的语言解决相同的问题 或者它们是不同的关注点 元编程方面是唯一的相似之处 即使在这方面 也存在很大的差异 您可以将宏的转换器视为从语法到语法的函数 就像您可
  • 如何将两个函数调用合并为一个?

    我想合并以下几行 let result1 add numbers let result2 add numbers n 变成这样的东西 let resultX add numbers gt add numbers n 我可以编写这样的函数吗
  • F# 查询串联

    我在用SqlDataConnectionF 中的数据提供程序迁移一些行 迁移的一部分是在 3 个表之间进行连接 如下所示 将其视为表的继承A B C where B and C继承自A所以我需要得到的是 类似 Linq Bs Join As
  • 不可为空字符串的 F# 类型别名

    我的代码中有一些域类型 我用它们来区分不同类型的字符串 因此编译器可以阻止我 例如以错误的顺序传递参数 type Foo string type Bar string let baz foo Foo bar Bar printfn A A
  • F# 有异步验证库吗?

    我在代码中经常使用 asyncResult 但它会在第一个错误时退出 asyncResult let a allGood let b thisReturnsError let c neverExecuted 但有时我想执行所有函数并总结错误
  • F# 中的异步 EF 查询

    在使用 EF6 的 C 中 我可以轻松地进行如下异步操作 using var context new MyDbContext var item await context SomeEntities Where e gt e Id 1 Fir
  • F# 中的组总计 - 使用序列很容易,可以使用列表吗?

    给定一组 id value 元组序列 很容易计算组总数 与使用 C 和 LINQ 执行此操作的方式几乎相同 let items g1 5 g2 10 g1 20 let groupsums items gt Seq groupBy fun
  • 与 F# List.nth 的参数顺序混淆

    List nth is T 列表 gt 整数 gt T 而不是标准int gt T 列表 gt T like Seq nth 这使得管道有些尴尬 难道幕后有什么事情吗 我不知道为什么 可能是为了ocaml兼容性 http www csc v
  • F# 是卡牌游戏 AI 的好语言吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何更改 Rx Builder 实现来修复堆栈溢出异常?

    我正在尝试提出一个 Rx Builder 以在 F 计算表达式语法中使用反应式扩展 我该如何修复它 以免堆栈崩溃 就像下面的 Seq 例子一样 是否有计划提供 RxBuilder 的实现作为响应式扩展的一部分或作为 NET Framewor
  • 在 Blazor 中显示计时器

    我正在尝试在服务器端 Blazor 应用程序中显示倒计时器 我的代码同时使用 F 和 C 语言 该代码在某种程度上可以工作 但计时器永远不会按预期停止 并且计时器显示偶尔不会呈现所有数字 这是我第一次尝试 Blazor 服务器端应用程序 我
  • 如何解决“程序主模块为空:运行时不会发生任何事情”

    我在 F 解决方案中有两个项目 1 主要项目有 EntryPoint http msdn microsoft com en us library dd402151 aspx并设置为启动项目 2 support 第二个项目 拥有一组支持模块
  • 如何在 FsCheck 中注册任意实例并让 xUnit 使用它?

    我有一个类型Average有一个字段count这是积极的int64 and a double字段称为sum 我做了一个任意的生成有效实例的操作 let AverageGen Gen map2 fun s c gt Average float
  • 如何在 F# 中将对象转换为泛型类型列表

    在下面的代码片段中 我的目的是将 System Object 可能是 FSharpList 转换为它所持有的任何泛型类型的列表 match o with list lt gt gt addChildList o gt list lt gt
  • 在 IEnumerable 上使用 Seq 函数 [重复]

    这个问题在这里已经有答案了 我正在尝试在 IEnumerable 上应用 Seq 函数 更具体地说 它是System Windows Forms HtmlElementCollection它实现了ICollection and IEnume
  • F# 中类型约束的顺序

    这适用于 F 4 0 type Something lt a b when b gt seq lt b gt gt 这不会 type Something lt b when b gt seq lt b gt a gt 类型名称中出现意外的符
  • 如何在MVVM中实现appSettings

    我正在尝试摆脱我使用的警告appSettings在 WPF 项目中 应用程序配置
  • F# 对于 OO 或命令式来说缺少什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐