我是.NET紧凑型框架的新手。我需要调用一个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函数什么是指向字节的指针而不是struct?
发布于 2012-05-18 13:05:46
问题是您的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即可。例如,智能设备框架代码至少有11个DeviceIoControl重载。这里有一些是为了给你一些味道:
[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);https://stackoverflow.com/questions/10649480
复制相似问题