Using P/Invoke correctly

扶醉桌前 提交于 2019-12-08 05:10:01

问题


I need to call an external dll from c#. This is the header definition:

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

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

I've added the enum and the call in 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);

This generates an AccessViolationException. I know the dll is 'working' because I've also added a call to GetHandle which returns the hHandle mentioned above. I've tried to change the param to an int (ref int watchmode) but get the same error. Doesn anyone know how I can PInvoke the above call?


回答1:


You're running into a parameter size problem difference between C# and C++. In the C++/windows world LONG is a 4 byte signed integer. In the C# world long is a 8 byte signed integer. You should change your C# signature to take an int.

ffpf is wrong in saying that you should use an IntPtr here. It will fix this particular problem on a 32 bit machine since an IntPtr will marshal as a int. If you run this on a 64 bit machine it will marshal as a 8 byte signed integer again and will crash.




回答2:


The Managed, Native, and COM Interop Team released the PInvoke Interop Assistant on codeplex. Maybe it can create the proper signature. http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120



来源:https://stackoverflow.com/questions/148856/using-p-invoke-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!