正确使用P/调用 [英] Using P/Invoke correctly

查看:124
本文介绍了正确使用P/调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从c#调用一个外部dll.这是标题定义:

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 );

我在C#中添加了枚举和调用:

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);

这将生成一个AccessViolationException.我知道dll正在运行",因为我还添加了对GetHandle的调用,该调用返回了上述的hHandle.我试图将参数更改为int(ref int watchmode),但得到相同的错误.没有人知道我该如何P调用上述电话吗?

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?

推荐答案

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

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在说您应该在此处使用IntPtr是错误的.由于IntPtr将封送为int,因此它将在32位计算机上解决此特定问题.如果在64位计算机上运行此命令,它将再次封送为8字节有符号整数,并且将崩溃.

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.

这篇关于正确使用P/调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆