Как работает extern в C #? - PullRequest
       17

Как работает extern в C #?

58 голосов
/ 25 февраля 2011

Всякий раз, когда я смотрю в отражатель достаточно глубоко, я сталкиваюсь с extern методами без источника.Я прочитал документацию msdn по адресу http://msdn.microsoft.com/en-us/library/e59b22c5(v=vs.80).aspx.. Из этой статьи я узнал, что методы с модификатором extern должны вводиться.Я интерпретировал это так, что он работает как абстрактный фабричный шаблон.Я также заметил, что никогда не видел нестатического метода extern.Является ли статическое объявление требованием (я мог понять, как это будет иметь смысл)?Я все еще догадываюсь здесь, и я не уверен, как это на самом деле работает.Мне кажется, что компилятор должен распознавать определенные атрибуты, которые смягчают обработку, но я не знаю, какие атрибуты отличаются от тех, с которыми я сталкивался, например MethodImplAttribute и DllImportAttribute из примера MSDN.Как кто-то использует атрибут extern?Он сказал, что во многих случаях это может повысить производительность.Кроме того, как мне найти источник extern методов, таких как Object.InternalGetEquals()?

Ответы [ 4 ]

95 голосов
/ 25 февраля 2011

Подумайте о прочтении раздела 10.6.7 спецификации C #, который отвечает на многие ваши вопросы. Я воспроизвожу здесь часть этого для вашего удобства:


Когда объявление метода включает модификатор extern, этот метод называется быть внешним методом. внешний методы реализуются извне, как правило, используя язык, отличный от C #. Потому что внешний метод декларация не дает фактического реализация, метод-тело внешний метод просто состоит из точка с запятой. Внешний метод не может быть родовым Внешний модификатор обычно используется в сочетании с Атрибут DllImport, позволяя внешним методам быть реализовано с помощью DLL (Dynamic Link Библиотеки). Среда исполнения может поддерживать другие механизмы, посредством которых реализации внешних методов могут быть предоставлены. Когда внешний метод включает атрибут DllImport, объявление метода также должно включите статический модификатор.


Как кто-то использует атрибут extern?

  • Напишите ваш код на неуправляемом языке по вашему выбору.
  • Скомпилируйте его в DLL, экспортируя точку входа вашего кода.
  • Создайте библиотеку взаимодействия, которая определяет метод как внешний метод в данной DLL.
  • Позвони с C #.
  • Profit!

Как мне искать источник внешних методов, таких как Object.InternalGetEquals ()?

Перейти к https://github.com/dotnet/coreclr/tree/master/src/vm

29 голосов
/ 25 февраля 2011

Методы, отмеченные 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);
   }
}

Он вызывает MessageBox, который определен в библиотеке Windows user32.dll. Runtime выполняет всю тяжелую работу за вас, хотя иногда вам придется вручную управлять памятью. Если вы ошиблись в подписи, ваша программа может перестать работать при вызове, вы можете ввести утечку или метод может вернуть что-то совершенно другое, поэтому будьте осторожны! Я считаю pinvoke.net отличным инструментом для исправления подписей для различных API.

Некоторые extern методы внутри .NET Framework, которые не имеют атрибута [DllImport], но украшены атрибутом [MethodImpl (MethodImplOptions.InternalCall)], обычно являются теми, которые реализованы в самой CLR. , который также написан на C. Некоторые из таких методов просто не могут быть реализованы в C #, потому что они сами управляют временем выполнения, а некоторые реализуются в C, потому что их производительность критична и C быстрее.

Вот что MSDN говорит о них:

Указывает внутренний вызов. Внутренний вызов - это вызов метода, который реализован в самой общеязыковой среде выполнения.

Что касается фактического кода реализации, я сомневаюсь, что вы сможете получить его от Microsoft, но есть несколько классных альтернативных реализаций CLR около , поэтому обязательно ознакомьтесь с ними.

3 голосов
/ 25 февраля 2011

extern с вызовом платформы (pinvoke) для упрощения вызова управляемых сборок в неуправляемый код. Ключевое слово extern информирует компилятор о том, что ему необходимо сгенерировать правильный код, чтобы обеспечить правильный маршалинг данных.

2 голосов
/ 05 октября 2015

Мы используем модификатор "extern" в объявлении метода.Он используется для указания того, что метод реализован извне.Обычно используется модификатор "extern" с атрибутом DllImport.Вызовы функций не из C # управляются с помощью этого атрибута.Если вы используете модификатор extern, вы должны включить следующее пространство имен:

using System.Runtime.InteropServices;

Синтаксис выглядит примерно так:

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

...