通过使用IntelliSense并查看其他人的代码,我遇到过这种IntPtr类型; 每次需要使用时,我只需要放置null或IntPtr.Zero发现大多数功能都可以使用.究竟是什么以及何时/为何使用它?
我有一个关于使用intptr_tvs. 的问题long int.我观察到递增内存地址(例如通过手动指针算术)因数据类型而异.例如,递增char指针会将1添加到内存地址,而递增int指针会为double添加4,8,为long double添加16等等...
起初我做了这样的事情:
char myChar, *pChar;
float myFloat, *pFloat;
pChar = &myChar;
pFloat = &myFloat;
printf( "pChar: %d\n", ( int )pChar );
printf( "pFloat: %d\n", ( int )pFloat );
pChar++;
pFloat++;
printf( "and then after incrementing,:\n\n" );
printf( "pChar: %d\n", (int)pChar );
printf( "pFloat: %d\n", (int)pFloat );
Run Code Online (Sandbox Code Playgroud)
编译和执行得很好,但XCode给了我警告我的类型转换:"从指针转换为不同大小的整数."
经过一些谷歌搜索和binging(后者还是一个词?),我看到有些人推荐使用intptr_t:
#include <stdint.h>
Run Code Online (Sandbox Code Playgroud)
...
printf( "pChar: %ld\n", ( intptr_t )pChar );
printf( "pFloat: %ld\n", ( intptr_t )pFloat );
Run Code Online (Sandbox Code Playgroud)
这确实解决了错误.所以,我想,从现在开始,我应该使用intptr_t类型转换指针...但是经过一些烦躁之后,我发现我可以通过替换int为long …
我想将托管代码中的对象传递给WinApi函数IntPtr.它会将此对象传递回托管代码中的回调函数IntPtr.它不是一个结构,它是一个类的实例.
如何转换object到IntPtr和回?
我有一个.dll(不是我自己的)有一个代表.该委托回调函数是:
"CallBackFN(ushort opCOde,IntPtr payload,uint size,uint localIP)"
如何将IntPtr转换为Byte []?我认为有效载荷实际上是Byte [].如果它不是Byte []而且它是其他东西我会丢失一些数据?
使用intptr_t作为通用存储(保存指针和整数值)而不是void*?(如下所示:http://www.crystalspace3d.org/docs/online/manual/Api1_005f0-64_002dBit-Portability-Changes.html)
对于我已经读过的内容:
int- > void*- > int往返不保证保持原值; 我猜int- > intptr_t- > int会的void*和intptr_t要求铸件,所以没有在这里得到好处void*表示存储指针时的显式转换次数较少,intptr_t表示存储整数值时转换次数较少intptr_t 需要C99我还应该考虑什么呢?
我想从IntPtr指针获取数据到字节数组.我可以使用以下代码来执行此操作:
IntPtr intPtr = GetBuff();
byte[] b = new byte[length];
Marshal.Copy(intPtr, b, 0, length);
Run Code Online (Sandbox Code Playgroud)
但是上面的代码强制从IntPtr到字节数组的复制操作.当有问题的数据很大时,这不是一个好的解决方案.
有没有办法将IntPtr转换为字节数组?例如,以下工作:
byte[] b = (byte[])intPtr
这将消除复制操作的需要.
另外:我们如何确定IntPtr指向的数据长度?
我有以下C++函数定义,我试图通过托管代码通过PInvoke调用:
bool FooBar(SIZE_T* arg1);
Run Code Online (Sandbox Code Playgroud)
我的管理声明如下:
[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref uint arg1);
Run Code Online (Sandbox Code Playgroud)
有些人可能会注意到我最终做的同样的错误.这不是64位便携式.SIZE_T的大小可变(32-64位),指针也是如此.在托管大小上,指针正确转换为64位,但uint没有,并且您最终可以在arg1的高位中使用垃圾.这是一个特别持久的错误,因为垃圾通常只是零:(
我已经开始工作的唯一解决方案是以下管理声明:
[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref IntPtr arg1);
Run Code Online (Sandbox Code Playgroud)
这当然有效,因为IntPtr可以正确地改变它的大小.在我的代码中,我只是将IntPtr视为一个整数,它可以工作,虽然它看起来像一个丑陋的黑客.在我看来应该有一些方法来正确指定,也许使用UnmanagedType.SysUInt,但我无法提出任何其他工作解决方案.
我在C#中导入WinApi函数,编写回调等(例子)并且总是想知道:
LRESULT作为最后的结果?W-PARAM?L-PARAM?WPARAM并且LPARAM有时包含结构.所以我需要将它们用作IntPtr.怎么样LRESULT?我安全int还是更好IntPtr?我在C#中使用什么类型的LRESULT? int还是IntPtr?
例如,在旧的.NET Framework 2.0源代码(Windows窗体,Visual Studio 2005 - Whidbey)中,使用HandleRef定义了GetClientRect函数:
[DllImport(ExternDll.User32, ExactSpelling=true, CharSet=CharSet.Auto)]
public static extern bool GetClientRect(HandleRef hWnd, [In, Out] ref NativeMethods.RECT rect);
Run Code Online (Sandbox Code Playgroud)
在新的Windows API代码包(来自Microsoft,2009/2010)中,使用IntPtr定义了相同的函数:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetClientRect(IntPtr hwnd, ref CoreNativeMethods.RECT rect);
Run Code Online (Sandbox Code Playgroud)
实际上,HandleRef不用于任何Windows API Code Pack源文件,而是在旧.NET Framework源文件中的本机方法签名中大量使用.
我想在一个带有参数IntPtr.Zero的函数中使用默认参数值IntPtr.这是不可能的,因为IntPtr.Zero它不是编译时常量.
有什么方法可以做我想做的事吗?