gpt4 book ai didi

f# - 为什么 F# 编译器在一种情况下给出错误,而在另一种情况下却没有?

转载 作者:行者123 更新时间:2023-12-04 19:06:52 24 4
gpt4 key购买 nike

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

int Foo(
ULONG_PTR *phHandle,
DWORD flags
);

在 F# 中,我认为 native 调用它的正确方法如下:
[<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

错误是:

A type instantiation involves a byref type. This is not permitted by the rules of 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

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

最佳答案

我认为定义 extern 无效F# 类中的方法。

如果你拉起F# 3.0 language specification并搜索 DllImport ,靠近底部的表格列出了一些特殊属性以及如何使用它们。 [<DllImport>] 的文本说:

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

这似乎表明只有声明 extern 才有效模块中定义的函数的方法(使用 [<DllImport>] );它没有说任何关于类(class)成员的事情。

我认为您遇到了编译器错误。请将此代码提交至fsbugs@microsoft.com所以他们可以修复编译器发出的错误消息——它应该给你一个关于定义 extern 的错误。类中的方法,因为语言规范不允许这样做。

关于f# - 为什么 F# 编译器在一种情况下给出错误,而在另一种情况下却没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22275072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com