我是.NET Compact Framework的新手。我需要调用DeviceIoControl函数,并将结构作为输入和输出参数传递给IOControl函数。
在PInvoke/DeviceIoControl中,我找到了如何访问该函数本身。但是,如何将指针传递为InBuf
和OutBuf
参数呢?
DeviceIoControl定义为P / Invoke:
[DllImport("coredll", 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);
有问题的结构具有以下布局:
struct Query
{
int a;
int b;
char x[8];
}
struct Response
{
int result;
uint32 success;
}
void DoIoControl ()
{
Query q = new Query();
Response r = new Response();
int inSize = System.Runtime.InteropServices.Marshal.SizeOf(q);
int outSize = System.Runtime.InteropServices.Marshal.SizeOf(r);
NativeMethods.DeviceIoControlCE((int)handle, (int)IOCTL_MY.CODE,
ref q, inSize, ref r, outSize, ref bytesReturned, IntPtr.Zero);
}
编辑:
当我尝试编译此代码时,出现错误:
cannot convert from 'ref MyNamespace.Response' to 'byte[]'
我如何将结构的地址传递给DeviceIoControl函数,该函数期望指向字节的指针而不是结构ref?
最佳答案
问题是您的P / Invoke声明与您的呼叫不匹配。 DeviceIoControl接受输入/输出参数的指针:
BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
因此,您可以通过多种方式“调整”声明。您提供的链接中的一个使用
byte[]
可能是为了方便起见。在您的情况下,由于您要传递简单的结构(即,没有内部指向其他数据的指针),因此最简单的“修复”方法是仅更改P / Invoke声明:[DllImport("coredll", SetLastError = true)]
internal static extern int DeviceIoControl(
IntPtr hDevice,
IOCTL.MY dwIoControlCode,
ref Query lpInBuffer,
int nInBufferSize,
ref Response lpOutBuffer,
int nOutBufferSize,
ref int lpBytesReturned,
IntPtr lpOverlapped);
而且您的代码应该可以工作。注意,我还更改了前两个参数的类型,以使调用代码更清晰,而无需强制转换。
编辑2
如果发现需要不同的签名,只需使P / Invoke重载即可。例如,Smart Device Framework代码的DeviceIoControl至少具有11个重载。以下只是其中一些给您的味道:
[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
internal static extern int DeviceIoControl<TInput, TOutput>(
IntPtr hDevice,
uint dwIoControlCode,
ref TInput lpInBuffer,
int nInBufferSize,
ref TOutput lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped)
where TInput : struct
where TOutput : struct;
[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
internal unsafe static extern int DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
void* lpInBuffer,
int nInBufferSize,
void* lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped);
[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
internal static extern int DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
IntPtr lpOutBuffer,
uint nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped);
[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
internal static extern int DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
byte[] lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped);
关于c# - NETCF如何通过ref将结构传递给DeviceIoControl,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10649480/