相当于C sharp" public IntPtr pHandle = IntPtr.Zero;"到德尔福" hp:Pointer"

时间:2014-11-13 18:59:01

标签: c# delphi pointers dll

经过一些研究后我翻译了

pHandle = IntPtr.Zero;

到Delphi

var
  pHandle: Pointer; 

当我在Delphi中打破调试时,我得到$314328,当我在C sharp上打破调试时,我得到一个整数值134180640。谁能告诉我如何正确翻译到Delphi?

我在Delphi中调用的Dll函数是:

function SAAT_Open(pHandle: Pointer): Boolean; stdcall;

C sharp功能是:

[DllImport("RFIDAPI.dll", EntryPoint = "SAAT_Open")]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool SAAT_Open(IntPtr pHandle);

2 个答案:

答案 0 :(得分:3)

在.NET中,IntPtr是一个指针类型的表示,它由一个整数在引擎盖下实现,因为它不能是一个真正的.NET指针(引用),因为必须管理“真正的”引用。但它也不能是一个真正的整数,或者你可能会对它进行数学运算,这是一种获得内存损坏的好方法。 (注意:此限制可能存在也可能不存在,具体取决于您使用的C#版本和/或CLR。)

但是因为你不能将IntPtr视为一个整数,所以你可以用它来做的唯一有用的事情是为它分配一个你从别处获得的值,或者将它传递给一些需要IntPtr的代码。 IntPtr.Zero用于解决一个缺失但非常重要的场景: null 值。您无法为0指定0或针对{{1}}对其进行测试,因为它不是参考,您无法对 null 进行分配或测试。因此,他们将其创建为一个特殊常量来表示“IntPtr,其值为null。”

如果你想在Delphi中做相同的操作,请声明指针,然后将其初始化为 nil

答案 1 :(得分:2)

  

经过一些研究后我翻译了

pHandle = IntPtr.Zero;
     

到Delphi

var
  pHandle: Pointer; 
     

有谁能告诉我如何正确翻译到Delphi?

C#语法允许您在声明变量的同一语句中初始化变量:

IntPtr Handle = IntPtr.Zero;

在Delphi中,您无法在声明它时初始化局部变量。所以你需要声明它,然后初始化它:

var
  Handle: Pointer;
....
Handle := nil;

在分配给非托管类型的局部变量之前,其值是未定义的。


但是,如果您将nil传递给SAAT_Open,则会失败。该函数需要一个非null句柄。因此,初始化为nil不会对您有所帮助。你需要做更多。您需要调用产生新句柄的函数。那是SAAT_TCPInit。您显示的C#代码将句柄初始化为空值,这样做是不必要的。也许这样做是因为SAAT_TCPInit被错误地翻译为使用句柄的ref参数,而不是正确的out参数转换。

虽然以上回答了您提出的问题,但它不会帮助解决您的问题。你不需要一个空句柄,你需要一个实际的句柄。


  

当我在Delphi中打破调试时,我得到$ 314328,当我在C sharp上打破调试时,我得到一个整数值134180640。

好吧,在pHandle = IntPtr.Zero之后,您绝对不会在C#中看到值134180640。您将看到值0。必须有一些其他代码初始化句柄。大概打电话给SAAT_TCPInit。你确实需要拨打电话。我相信你这样做了。

句柄在后续执行程序时不一定具有相同的值。并且不需要在每个不同的程序中具有相同的值。句柄实际上是一个动态分配的指针,其地址在一次运行到另一次运行时是可变的。因此,如果它随着您的观察而变化,则无需担心。如果SAAT_TCPInit返回True表示成功,则句柄值将有效。