为什么F#编译器在一种情况下给出错误,而在另一种情况下却没有给出错误? [英] Why does the F# compiler give an error for one case but not the other?
问题描述
我正在从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类型.通用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
为什么将它编译为模块而不是类?
我认为在F#的类中定义extern
方法无效.
如果您拉起 F#3.0语言规范并搜索DllImport
,则底部附近是该表列出了一些特殊属性以及如何使用它们. [<DllImport>]
的文本说:
应用于模块中的函数定义时,导致F#编译器忽略该定义的实现,而是将其编译为CLI P/Invoke存根声明.
这似乎表明仅在模块中定义的函数上声明extern
方法(使用[<DllImport>]
)是有效的;它并没有说任何关于班级成员的事情.
我认为您正在遇到编译器错误.请将此代码提交给fsbugs@microsoft.com
,以便它们可以修复编译器发出的错误消息-实际上,这会给您关于在类中定义extern
方法的错误,因为语言规范不允许这样做.>
I'm working on a platform invoke call from F#, and I am getting a compiler error I really can't make that much sense out of. First, let me show the C signature of what I am doing:
int Foo(
ULONG_PTR *phHandle,
DWORD flags
);
In F#, I think the correct way to invoke this natively is as so:
[<DllImport("somedll.dll")>]
static extern int APlatformInvokeCall
(
[<Out>]nativeint& phHandle,
uint32 flags
)
If I try to call this in a class, I get a compilation error when calling it like so:
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
The error is:
A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
Weirdly, when I do this all in a module, the compilation errors go away:
module Module1 =
[<DllImport("somedll.dll")>]
extern int APlatformInvokeCall
(
nativeint& phHandle,
uint32 flags
)
let Foo() =
let mutable thing = nativeint 0
APlatformInvokeCall(&thing, 0u) |> ignore
thing
Why does this compile as a module, but not as a class?
I don't think it's valid to define an extern
method within a class in F#.
If you pull up the F# 3.0 language specification and search for DllImport
, near the bottom is a table listing some special attributes and how they can be used. The text for [<DllImport>]
says:
When applied to a function definition in a module, causes the F# compiler to ignore the implementation of the definition, and instead compile it as a CLI P/Invoke stub declaration.
That seems to indicate that it's only valid to declare extern
methods (that use [<DllImport>]
) on functions defined in a module; it doesn't say anything about class members though.
I think you're running into a compiler bug. Please submit this code to fsbugs@microsoft.com
so they can fix the error message emitted by the compiler -- it should really be giving you an error about defining an extern
method in a class since that's not allowed by the language spec.
这篇关于为什么F#编译器在一种情况下给出错误,而在另一种情况下却没有给出错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!