В общем, найти авторитетную ссылку для объявлений P / Invoke сложно, если вы недостаточно знаете о C, чтобы сделать объявление правильным. В Интернете много плохих объявлений. Типичными ловушками являются объявления VB6, их существует lot , где аргументы, которые действительно являются int, объявляются как Long. Long - это 32-битный целочисленный тип в VB6, Integer - 16-битный по историческим причинам.
Другая распространенная ошибка - использование int, когда требуется IntPtr. Эти объявления прекрасно работают в 32-битном режиме, но плохо себя ведут в 64-битном режиме. Особенно проблематичны функции, которые принимают 4 или менее аргументов, неправильный тип аргумента не генерирует предупреждение PInvokeStackImbalance MDA, поскольку первые 4 аргумента функции передаются в регистрах ЦП. Эта ошибка имеет тенденцию кусаться еще долго после того, как автор объявил о выполненной работе, довольно сложно вернуться к ней и диагностировать проблему.
Следующая неприятность - это утомительная процедура объявления и поддержки объявлений P / Invoke или оболочек C ++ / CLI. Когда неуправляемый API велик, вы в конечном итоге напишите о многих из них. Каждый из них готов дать вам сложную диагностику ошибки во время выполнения, когда вы ее слегка ошибочно.
Действительно жесткое взаимодействие с COM-серверами, которые имеют интерфейсы на основе IUnknown. Такие серверы не имеют библиотеки типов, поэтому нет возможности использовать Tlbimp.exe для автоматического создания библиотеки взаимодействия. Вы должны повторно объявить интерфейсы в вашем коде C # и убедиться, что вы правильно получили [Guid] и объявления методов. Отсутствие поддержки множественного наследования требует перехода через дополнительные циклы, когда интерфейс наследуется от промежуточного интерфейса на основе IUnknown. Проблема в том, что этот автор неправильно называет «налог на наследство».
Такого рода серверы встречаются чаще, чем кажется на первый взгляд. Например, все, что вы хотите сделать с оболочкой (explorer.exe), основано на IUnknown. Так же как и расширения Vista и Win7, умело заключенные в пакет Windows API Code Pack.
И да, обработка ошибок. Слишком много неуправляемого кода, который не возвращает ничего, кроме недружественного кода ошибки, такого как E_FAIL или E_UNEXPECTED. И не реализует IErrorInfo, так что все, что вы получите, - это бесполезное обобщенное сообщение, на которое нужно смотреть. Или API, которые возвращают BOOL для обозначения сбоя, предлагая программисту просто игнорировать возвращаемое значение. И AccessViolation, или Fatal Engine Execution Error, неуправляемый код взорвался вам в лицо, не оставляя никаких крошек, чтобы выяснить, что пошло не так. Это не относится к взаимодействию с C #, такой код трудно кому-либо использовать.
Кроме этого, обычно довольно просто заставить его работать. Маршаллер P / Invoke и поддержка взаимодействия COM в .NET действительно превосходны и значительно лучше, чем то, что доступно в других виртуальных машинах.