我正在尝试将C#写成以下内容:
typedef struct BATT_ID
{
UINT8 nBattID[8];
} BATT_ID, *PBATT_ID;
HANDLE g_hDevice;
// Connect to the driver
g_hDevice = CreateFile(L"BAT1:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
void GetBattID(PBATT_ID pBattId)
{
// ... snipped code to check g_hDevice is valid ...
DeviceIoControl(g_hDevice, SOMO650_PWR_GET_BATT_ID, NULL, 0, pBattId, sizeof(BATT_ID), dwByteReturn, NULL))
}
// once BATT_ID has been filled it can be formatted as follows
wsprintf(strInfo, TEXT("%02X:%02X:%02X:%02X:%02X:%02X"), BattID.nBattID[6], BattID.nBattID[5], BattID.nBattID[4], BattID.nBattID[3], BattID.nBattID[2], BattID.nBattID[1]);
代码连接到Windows Mobile设备的电源驱动程序并尝试检索电池ID 这是针对SoMo650的最新ROM版本,Socket只能用C语言提供示例代码。
除了调用DeviceIoControl之外,我可以成功完成所有事情(尽我所知),因为我不知道如何将BATT_ID结构转换为C#。
我猜这是因为它是一个结构,而DeviceIoControl需要一个指针,我应该看看Marshal.PtrToStructure(),但我的C经验非常少,感觉非常深刻。
任何协助都将不胜感激。
答案 0 :(得分:5)
您可能最好使用具有电池控制功能的Smart Device Framework。请点击此处查看社区版的下载链接。
修改:如果你仍然想要结构的pinvoke相当于这里:
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct BATT_ID { [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I8)] public int[] nBattId; };
然后在p /调用之前,您需要签名为“DeviceIoControl”,如下所示:
[DllImport("coredll.dll", EntryPoint="DeviceIoControl", SetLastError=true)] internal static extern int DeviceIoControlCE( int hDevice, int dwIoControlCode, byte[] lpInBuffer, int nInBufferSize, byte[] lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped);
电话会是这样的:
IntPtr ptr = IntPtr.Zero; BATT_ID battId; int sz = Marshal.SizeOf(battId.GetType()); ptr = Marshal.AllocHGlobal(sz); Marshal.StructureToPtr((BATT_ID)battId, ptr, false); byte[] pBattId = ptr.ToPointer(); out int bytesReturned = 0; DeviceIoControl(handle, IOCONTROL_ID, null, 0, pBattId, sz, ref bytesReturned, IntPtr.Zero); battId = Marshal.PtrToStructure(ptr, battId.GetType()); Marshal.FreeHGlobal(ptr);
我希望我有这个权利......
编辑#2:正如 ctacke (谢谢!)指出我的代码示例错误...
unsigned byte[8] battId; DeviceIoControl(g_hDevice, SOMO650_PWR_GET_BATT_ID, null, 0, battId, Marshal.SizeOf(battId), ref bytesReturned, IntPtr.Zero);
答案 1 :(得分:3)
基本上你有一个8字节的结构。只需将8字节长的byte []传入DeviceIoControl调用即可。没有必要打电话给AllocHGlobal,或做任何其他古怪的编组。