什么时候使用extern关键字而不使用[DllImport]属性合适? [英] When is it appropriate to use the extern keyword without using the [DllImport] attribute?
问题描述
今天,当我注意到 extern
关键字文档声明:
外部修饰符用于声明在外部实现的方法。当您使用Interop服务调用非托管代码时,extern修饰符的 常见用法 带有DllImport属性。
引起我注意的是该文档指出 extern
的常用是它与DllImport属性一起使用。这意味着存在其他不需要DllImport的用例。我不必将许多外部非托管库集成到我的应用程序中,但在所有情况下,链接方法都是使用DllImport定义的。
我搜索了多个查询通过Google和MSDN,我找不到在没有将方法定义为从非托管dll导入外部方法的情况下何时使用 extern
关键字的案例或解释。 / p>
如何以及何时使用 extern
关键字而不定义 [DllImport(...)]
方法定义上的属性?
请注意,这并非专门用于 extern
定义别名时。这是该关键字的另一种用法,这种情况在另一篇文章中中概述了在MSDN C#语言参考中。
我要使用它的一种情况是,如果我是实现Microsoft的开发人员对CLR本身中定义的方法的调用。就像在 GC._WaitForFullGCApproach
中一样:
[MethodImpl(MethodImplOptions.InternalCall)]
私有静态外部整数_WaitForFullGCApproach(int millisecondsTimeout);
注意:否 DllImport
。当然,这有点作弊-这仍然是对非托管方法的调用,只是没有显式引用DLL。但是,凡人不能调用此类代码,因为它仅在 mscorlib
程序集中有效。
InternalCall
是为COM生成的互操作类型:
命名空间Microsoft.Office。 Interop.Excel {
[DefaultMember( _ Default)]
[ClassInterface(0)]
[ComSourceInterfaces( Microsoft.Office.Interop.Excel.AppEvents\0)]
[Guid( 00024500-0000-0000-C000-000000000046)]
[TypeLibType(2)]
[ComImport]
公共类ApplicationClass {
// ...
[DispId(302)]
[MethodImpl(MethodImplOptions.InternalCall)]
公共虚拟外部void Quit();
// ...
}
}
属性允许运行时将方法调用解析为对COM接口的调用。显然,在 mscorlib
之外有效使用 InternalCall
。您通常不会自己用C#编写这样的代码。
C#语言规范比MSDN更加详细:
extern
修饰符通常与DllImport $ c $结合使用c>
属性(第17.5.1节),允许
DLL(动态链接库)实现外部方法。执行环境可以支持
其他机制,从而可以提供
的外部方法的实现。
来自实现从立场上来说,将方法标记为 extern
仅具有将方法的RVA(相对虚拟地址)设置为0的作用,将其标记为没有实现。诸如 DllImport
(和 MethodImpl
)之类的属性对于向运行时描述如何定位方法的实际实现是必需的。 ECMA-335的第I.9.4节方法实现元数据(以及 DllImport
和 InternalCall
C#编译器将允许您将方法标记为 extern
和不使用任何属性来指示实现所在的位置,但是具有这种方法的任何类型在运行时都将导致 TypeLoadException
。
I was re-reading through some .Net documentation today when I noticed that the first portion of the extern
keywords documentation claims:
The extern modifier is used to declare a method that is implemented externally. A common use of the extern modifier is with the DllImport attribute when you are using Interop services to call into unmanaged code.
What caught my attention was that the document states that "a common use" of extern
is that it is used with the DllImport attribute. This implies that there are other use-cases where DllImport is not required. I've not had to integrate many external, non-managed libraries into my applications but in all cases the linked methods were defined with DllImport.
I've searched multiple queries through Google and MSDN and I can't find a case or explanation of when the extern
keyword would be used without defining the method as an external method import from an unmanaged dll.
How, and when, would you use the extern
keyword without defining the [DllImport(...)]
attribute on the method definition?
Please note, this is not specific to using extern
when defining aliases. That is a different use of the keyword and that case is outlined in a different article within the MSDN C# language reference.
One case where I'd use it is if I were a Microsoft developer implementing a call to a method defined in the CLR itself. Like in GC._WaitForFullGCApproach
:
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int _WaitForFullGCApproach(int millisecondsTimeout);
Note: no DllImport
. Of course this is cheating a bit -- this is still a call to an unmanaged method, just not with an explicit reference to a DLL. Mere mortals cannot invoke such code, though, since it's valid only in the mscorlib
assembly.
Another application of InternalCall
is in interop types generated for COM:
namespace Microsoft.Office.Interop.Excel {
[DefaultMember("_Default")]
[ClassInterface(0)]
[ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents\0")]
[Guid("00024500-0000-0000-C000-000000000046")]
[TypeLibType(2)]
[ComImport]
public class ApplicationClass {
// ...
[DispId(302)]
[MethodImpl(MethodImplOptions.InternalCall)]
public virtual extern void Quit();
// ...
}
}
The attributes allow the runtime to resolve the method call as an invocation to a COM interface. This use of InternalCall
is valid outside mscorlib
, obviously. You would not typically write such code in C# yourself; it's generated on demand when you add a COM type library as a reference.
The C# language specification goes into slightly more detail than the MSDN:
The
extern
modifier is typically used in conjunction with aDllImport
attribute (§17.5.1), allowing external methods to be implemented by DLLs (Dynamic Link Libraries). The execution environment may support other mechanisms whereby implementations of external methods can be provided.
From an implementation standpoint, marking a method extern
only has the effect of setting the RVA (relative virtual address) of the method to 0, marking it as having no implementation. Attributes like DllImport
(and MethodImpl
) are necessary to describe to the runtime how to locate the method's actual implementation. This is described in secion I.9.4 of ECMA-335, "Method implementation metadata" (and DllImport
and InternalCall
seem to be the only ways currently available).
The C# compiler will allow you to mark a method as extern
and not use any attribute to indicate where the implementation lives, but any type with such a method will result in a TypeLoadException
at runtime.
这篇关于什么时候使用extern关键字而不使用[DllImport]属性合适?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!