маршаллинг C и C#

У меня есть следующий код сортировки в моем проекте. У меня есть несколько вопросов по этому поводу.

[DllImport=(Core.dll, SetLastError=true, EntryPoint="CoreCreate", CharSet="CharSet.Ansi", CallingConvention="CallingConvention.Cdecl")]
internal static extern uint CoreCreate(ref IntPtr core);
  1. Почему требуется 'internal static extern'? Это обязательно? Почему это используется?
  2. Что такое SetLastError?
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
internal struct Channel
{
internal byte LogicalChannel;
}

Почему LayoutKind.Sequential?


person SHRI    schedule 10.10.2012    source источник
comment
я думаю, что эта статья поможет msdn.microsoft.com /en-us/library/aa288468(v=vs.71).aspx   -  person Prasad    schedule 10.10.2012
comment
Кажется, это более чем один вопрос, и, вероятно, его следует создать в виде отдельных сообщений.   -  person musefan    schedule 10.10.2012


Ответы (2)


Почему требуется «внутренний статический внешний вид»?

Модификатор internal просто устанавливает видимость вашего метода. Это не обязательно должно быть internal, поэтому вы можете объявить метод private или public по своему усмотрению и так же, как и любой другой стандартный метод.

Модификатор static необходим, потому что это не метод экземпляра и этот метод не знает никакого класса (у него нет указателя this).

Наконец, extern требуется, чтобы сообщить компилятору, что метод реализован не здесь, а в другом месте (и вы укажете, где, используя атрибуты). Метод Evey extern тоже должен быть объявлен static (поскольку это простой вызов функции без каких-либо знаний об объектах).

Что такое SetLastError?

Это указывает на то, что метод может изменить значение кода последней ошибки потока. См. GetLastError(). для получения подробной информации об этом. Если вызываемая функция изменит это значение, рекомендуется установить SetLastError на true из MSDN:

Упаковщик времени выполнения вызывает GetLastError и кэширует возвращенное значение, чтобы предотвратить его перезапись другими вызовами API. Вы можете получить код ошибки, вызвав GetLastWin32Error.

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

Почему LayoutKind.Sequential?

Макет класса в .NET не обязательно должен быть последовательным в памяти (последовательный = если A объявлен до B, тогда макет памяти имеет A перед B). Это неверно в C, где порядок объявления имеет значение (объявление используется компилятором для понимания расположения в памяти необработанных данных). Если вам нужно взаимодействовать с функциями C, вы должны быть уверены в расположении данных, которые вы им передаете. Вот как работает LayoutKind.Sequential: он указывает компилятору соблюдать последовательный порядок объявления данных в struct. Это не единственный вариант взаимодействия с неуправляемым миром, вы даже можете явно задать смещение (от начала структуры) каждого поля (см. LayoutKind.Explicit).

person Adriano Repetti    schedule 10.10.2012

Это не ответ, просто несколько комментариев: «внутренняя статика» — это одно, а «внешняя» — это другое, что необходимо при вызове внешних dll. SetLastError или GetLastError — это методы, которые мы часто использовали в «старые» дни для получения сообщений об ошибках из окон о последней обработке. LayoutKind.Sequential — это способ сообщить компилятору о необходимости компоновки структуры определенным образом — вам может понадобиться сделать это при переходе на другие системы.

person Peter Larsen 'CPH'    schedule 10.10.2012
comment
Возможно, тогда опубликуйте это как комментарий вместо ответа? - person musefan; 10.10.2012
comment
Значит, это должен быть комментарий. Кроме того, пара static extern необходима для DllImport. Следовательно, internal — это одно, а static extern — другое. - person Dennis; 10.10.2012
comment
Полегче, ребята - кажется, мне еще не разрешено добавлять комментарии к вопросам !! - person Peter Larsen 'CPH'; 10.10.2012