【问题标题】:Using P/Invoke correctly正确使用 P/Invoke
【发布时间】:2008-09-29 14:18:17
【问题描述】:

我需要从 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 上述调用?

【问题讨论】:

    标签: c# windows interop pinvoke


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2011-04-20
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 2014-02-24
        • 2011-05-02
        相关资源
        最近更新 更多