extern 在 C# 中如何工作?

发布于 2024-10-19 15:37:36 字数 625 浏览 3 评论 0原文

每当我足够深入地研究反射器时,我都会遇到没有来源的 extern 方法。我阅读了 http://msdn 上的 msdn 文档。 microsoft.com/en-us/library/e59b22c5(v=vs.80).aspx。我从那篇文章中得到的是,必须注入带有 extern 修饰符的方法。我将此解释为它的工作原理类似于抽象工厂模式。我还注意到我从未见过非静态外部方法。静态声明是一个要求吗(我可以看出这有什么意义)?我仍然在这里猜测,我不确定它实际上是如何工作的。在我看来,编译器必须识别某些可以减轻处理的属性,但除了我遇到的诸如 MethodImplAttributeDllImportAttribute 之类的属性之外,我不知道这些属性是什么> 来自 MSDN 示例。人们如何利用 extern 属性?它说在许多情况下这可以提高性能。另外,我将如何研究 extern 方法(如 Object.InternalGetEquals())的来源?

Whenever I look deeply enough into reflector I bump into extern methods with no source. I read the msdn documentation at http://msdn.microsoft.com/en-us/library/e59b22c5(v=vs.80).aspx. What I got from that article is that methods with the extern modifier have to be injected. I interpreted this to mean it works something like an abstract factory pattern. I also noticed that I've never seen a non-static extern method. Is static declaration a requirement (I could see how this would make sense)? I'm still guessing here and I'm not sure how it actually works. It seems to me like the compiler must recognize certain attributes that mitigate processing, but I don't know what the attributes are other than ones I've come across like MethodImplAttribute and DllImportAttribute from the MSDN example. How does someone leverage the extern attribute? It said that in many instances this can increase performance. Also, how would I go about looking into the source of extern methods like Object.InternalGetEquals()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

彩扇题诗 2024-10-26 15:37:36

请考虑阅读 C# 规范的第 10.6.7 节,它回答了您的许多问题。为了您的方便,我在这里复制了部分内容:


当方法声明包含
extern修饰符,该方法是说
成为外部方法。外部的
方法是在外部实现的,
通常使用除
C#。因为外部方法
声明没有提供实际的
实现,方法体
外部方法简单地包含一个
分号。外部方法可能不会
是通用的。外部修饰符是
通常与
DllImport 属性,
允许外部方法
由DLL(动态链接
图书馆)。执行环境
可以支持其他机制
外部方法的实现
可以提供。当外部
方法包含 DllImport 属性,
方法声明还必须
包含静态修饰符。


如何利用 extern 属性?

  • 使用您选择的非托管语言编写代码。
  • 将其编译为 DLL,导出代码的入口点。
  • 创建一个互操作库,将该方法定义为给定 DLL 中的外部方法。
  • 从 C# 调用它。
  • 利润!

我如何去研究外部方法(如 Object.InternalGetEquals())的来源?

转到 https://github.com/dotnet/coreclr/tree/master/src /vm

Consider reading section 10.6.7 of the C# specification, which answers many of your questions. I reproduce part of it here for your convenience:


When a method declaration includes an
extern modifier, that method is said
to be an external method. External
methods are implemented externally,
typically using a language other than
C#. Because an external method
declaration provides no actual
implementation, the method-body of an
external method simply consists of a
semicolon. An external method may not
be generic. The extern modifier is
typically used in conjunction with a
DllImport attribute,
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. When an external
method includes a DllImport attribute,
the method declaration must also
include a static modifier.


How does someone leverage the extern attribute?

  • Write your code in the unmanaged language of your choice.
  • Compile it into a DLL, exporting the entry point of your code.
  • Make an interop library that defines the method as an extern method in the given DLL.
  • Call it from C#.
  • Profit!

How would I go about looking into the source of extern methods like Object.InternalGetEquals()?

Go to https://github.com/dotnet/coreclr/tree/master/src/vm

南烟 2024-10-26 15:37:36

标记为 extern[DllImport] 属性通常是对 C 库的调用。此功能对于调用 WinAPI 或遗留代码非常有用。

这是来自 MSDN 的示例:

using System;
using System.Runtime.InteropServices;
class MainClass 
{
   [DllImport("User32.dll")]
   public static extern int MessageBox(int h, string m, string c, int type);

   static int Main() 
   {
      string myString; 
      Console.Write("Enter your message: ");
      myString = Console.ReadLine();
      return MessageBox(0, myString, "My Message Box", 0);
   }
}

它调用在 Windows user32.dll 库中定义的 MessageBox。运行时在这里为您完成所有繁重的工作,尽管有时您需要手动管理内存。如果你的签名错误,你的程序可能会在调用时失败,你可能会引入泄漏,或者该方法可能会返回完全不同的东西,所以要小心!我发现 pinvoke.net 是纠正不同 API 签名的好工具。

.NET Framework 中的一些 extern 方法没有 [DllImport] 属性,但用 [MethodImpl (MethodImplOptions.InternalCall)] 属性通常是 CLR 本身实现的,也是用 C 编写的。其中一些方法无法在 C# 中实现,因为它们本身管理运行时,而另一些则在 C 中实现,因为它们的性能至关重要,而且 C 更快。

这是 MSDN 关于它们的说法

指定内部调用。内部调用是对公共语言运行时本身内实现的方法的调用。

至于查看实际的实现代码,我怀疑你能否从微软获得它,但是有 一些很酷的 CLR 替代实现,所以一定要检查它们。

Methods marked extern with [DllImport] attribute are usually calls to C libraries. This feature is useful for calling WinAPI or legacy code.

This is example from MSDN:

using System;
using System.Runtime.InteropServices;
class MainClass 
{
   [DllImport("User32.dll")]
   public static extern int MessageBox(int h, string m, string c, int type);

   static int Main() 
   {
      string myString; 
      Console.Write("Enter your message: ");
      myString = Console.ReadLine();
      return MessageBox(0, myString, "My Message Box", 0);
   }
}

It calls MessageBox which is defined inside Windows user32.dll library. Runtime does all the heavy work for you here, although sometimes you'd need to manually manage memory. If you get the signature wrong, your program may fail on the call, you may introduce a leak or the method might return something completely different, so be careful! I find pinvoke.net a great instrument to correct signatures for different APIs.

Some extern methods inside .NET Framework that don't have have [DllImport] attribute but are decorated with [MethodImpl (MethodImplOptions.InternalCall)] attribute are usually the ones implemented in CLR itself, which is written in C as well. Some of such methods just can't be implemented in C# because they manage runtime itself, and some are implemented in C because their performance is critical and C is faster.

This is what MSDN says about them:

Specifies an internal call. An internal call is a call to a method that is implemented within the common language runtime itself.

As for looking at the actual implementation code, I doubt you'll be able to get it from Microsoft but there are some cool alternative implementations of CLR around so be sure to check them out.

街道布景 2024-10-26 15:37:36

extern 是使用平台调用 (pinvoke) 来促进托管程序集调用非托管代码。 extern 关键字通知编译器需要生成正确的代码以允许正确的数据封送。

extern is with platform invocation (pinvoke) to facilitate managed assemblies calling into unmanaged code. The extern keyword informs the compiler that it will need to generate the correct code for allow for the correct data marshaling.

树深时见影 2024-10-26 15:37:36

我们在方法声明中使用“ extern ”修饰符。它用于指示该方法是外部实现的。 “ extern ”修饰符的常见用途是与 DllImport 属性一起使用。非 C# 函数调用使用此属性进行管理。
如果您使用 extern 修饰符,则必须包含以下命名空间:

using System.Runtime.InteropServices;

语法类似于:

[DllImport("User32.dll")]
公共静态 extern int MessageBox(int h, 字符串 m, 字符串 c, int 类型);

We use " extern " modifier in method declaration. It is used to indicate that the method is implemented externally. A common use of the " extern " modifier is with the DllImport attribute. Non-C# function calls are managed with this attribute.
If you are using extern modifier then you have to include following namespace:

using System.Runtime.InteropServices;

Syntax is somthing like:

[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文