2012-05-18 1 views
2

저는 .NET Compact Framework를 처음 사용합니다. DeviceIoControl 함수를 호출하고 IOControl 함수에 입력 및 출력 매개 변수로 구조체를 전달해야합니다.NETCF 어떻게하면 DeviceIoControl ref로 구조체를 전달합니까?

PInvoke/DeviceIoControl에서 함수 자체에 액세스하는 방법을 찾았습니다. 하지만 포인터를 구조체 InBufOutBuf 매개 변수로 전달하는 방법은 무엇입니까?

의 DeviceIoControl은 P/호출로 정의된다 : 나는 내가 얻을이 코드를 컴파일 할 때 :

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); 
} 

편집 : 문제

[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); 

구조는이 레이아웃이 오류 :

cannot convert from 'ref MyNamespace.Response' to 'byte[]' 

DeviceIoControl 함수에 구조체의 주소를 전달하여 struct ref 대신 byte 포인터를 기대하는 방법은 무엇입니까?

답변

2

P/Invoke 선언이 사용자의 호출과 일치하지 않는 것이 문제입니다. DeviceIoControl을은/아웃 paramters에 대한 포인터에 취

BOOL DeviceIoControl(
    HANDLE hDevice, 
    DWORD dwIoControlCode, 
    LPVOID lpInBuffer, 
    DWORD nInBufferSize, 
    LPVOID lpOutBuffer, 
    DWORD nOutBufferSize, 
    LPDWORD lpBytesReturned, 
    LPOVERLAPPED lpOverlapped 
); 

그래서 당신은 많은 방법에있는 당신의 선언을 "조정"할 수 있습니다. 귀하가 제공하는 링크에있는 하나의 링크는 편리함을 위해 byte[]을 사용합니다. 당신이 (다른 데이터 즉, 어떤 내부 포인터) 간단한 구조체를 통과하지하고 있기 때문에 귀하의 경우에는, 다음, 가장 쉬운 "수정"당신에게 P/호출 선언 변경하는 것입니다 :

[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/호출에 과부하가. 예를 들어, Smart Device Framework 코드에는 DeviceIoControl에 대한 과부하가 11 개 이상 있습니다. 다음은 그 중 일부입니다.

+0

Chris, 내가 원하는 것을 설명하기 위해 코드를 포함 시켰지만 실제 질문을 놓쳤습니다. 컴파일러 오류가 발생하기 때문에 함수를 호출하지 않았 음이 분명합니다. – harper

+0

감사합니다. 내가 돌아 왔을 때 나는 이것을 점검 할 것이다. 그러나 ioctl 함수는 코드에 따라 많은 호출을 수행하도록 설계되었습니다. 각 코드에 대해 inBuf 및 outBuf의 구조가 변경 될 수 있습니다. 그래서 다음 코드에는 다른 유형이 필요합니다. C++은 C#이하지 않는 조합을 허용합니다. 이 다양한 유형의 in/outBuf는 어떻게 처리합니까? – harper

+0

다른 P/Invoke 선언을 사용합니다. 본질적으로 많은 오버로드가 발생합니다. 스마트 장치 프레임 워크에서 여러 답변을 업데이트 해 보겠습니다. – ctacke

관련 문제