Вопрос

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

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), но получаю ту же ошибку.Кто-нибудь знает, как я могу вызвать вышеуказанный вызов?

Это было полезно?

Решение

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top