1

我需要从 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上述内容的调用。我试图将参数更改为int( ref int watchmode) 但得到相同的错误。有谁知道我如何 PInvoke 上述调用?

4

2 回答 2

8

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

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

于 2008-09-29T18:33:13.273 回答
4

托管、本机和 COM 互操作团队在 codeplex 上发布了 PInvoke 互操作助手。也许它可以创建正确的签名。 http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120

于 2008-10-17T03:11:22.370 回答