Использование P / Invoke правильно - PullRequest
1 голос
/ 29 сентября 2008

Мне нужно вызвать внешнюю DLL из c #. Это определение заголовка:

enum WatchMode { 
   WATCH_MODE_SYSTEM = 0,          
   WATCH_MODE_APPLICATION  = 1 };  

LONG ADS_API WDT_GetMode ( LONG i_hHandle, WatchMode * o_pWatchMode );

Я добавил перечисление и вызов в C #:

public enum WatchMode
{
    WATCH_MODE_SYSTEM = 0,
    WATCH_MODE_APPLICATION = 1       
}
[DllImport("AdsWatchdog.dll")]
internal static extern long WDT_GetMode(long hHandle, ref WatchMode watchmode);

Это создает исключение AccessViolationException. Я знаю, что dll работает, потому что я также добавил вызов GetHandle, который возвращает hHandle, упомянутый выше Я попытался изменить параметр на int (ref int watchmode), но получил ту же ошибку. Кто-нибудь знает, как я могу вызвать вышеуказанный вызов?

Ответы [ 2 ]

7 голосов
/ 29 сентября 2008

Вы столкнулись с проблемой разницы в параметрах между C # и C ++. В мире C ++ / windows LONG - это 4-байтовое целое число со знаком. В мире C # long - 8-байтовое целое число со знаком. Вы должны изменить свою подпись C #, чтобы получить int.

ffpf неверно говорит, что вы должны использовать IntPtr здесь. Это решит эту конкретную проблему на 32-битной машине, поскольку IntPtr будет маршалировать как int. Если вы запустите это на 64-битной машине, он снова будет выглядеть как 8-байтовое целое число со знаком и вылетит.

4 голосов
/ 17 октября 2008

Команда взаимодействия Managed, Native и COM выпустила PInvoke Interop Assistant для кодового комплекса. Может быть, это может создать правильную подпись. http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120

...