正确使用P / Invoke

时间:2008-09-29 14:18:17

标签: c# windows interop pinvoke

我需要从c#调用外部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。我试图将参数更改为intref int watchmode),但得到的错误相同。没有人知道我怎么能拨打上述电话吗?

2 个答案:

答案 0 :(得分:7)

您遇到了C#和C ++之间的参数大小问题差异。在C ++ / windows世界中,LONG是一个4字节的有符号整数。在C#world中,long是一个8字节的有符号整数。您应该更改C#签名以获取int。

ffpf说你应该在这里使用IntPtr是错误的。它将在32位机器上解决这个特殊问题,因为IntPtr将作为int编组。如果你在64位机器上运行它,它将再次编组为8字节有符号整数并将崩溃。

答案 1 :(得分:4)

Managed,Native和COM Interop团队在codeplex上发布了PInvoke Interop Assistant。也许它可以创造适当的签名。 http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120