NETCF كيف يمكنني تمرير البنية حسب المرجع إلى DeviceIoControl

StackOverflow https://stackoverflow.com//questions/10649480

  •  11-12-2019
  •  | 
  •  

سؤال

أنا جديد على إطار العمل المضغوط .NET.أحتاج إلى استدعاء وظيفة DeviceIoControl وتمرير الهياكل كمعلمات الإدخال والإخراج إلى وظيفة IOControl.

في PInvoc/DeviceIoControl لقد وجدت كيفية الوصول إلى الوظيفة نفسها.ولكن كيف يمكنني تمرير مؤشر البنية كما InBuf و OutBuf معامل؟

يتم تعريف DeviceIoControl على أنه P/Invoc:

[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 التي تتوقع أن يكون المؤشر بايتًا بدلاً من مرجع البنية؟

هل كانت مفيدة؟

المحلول

تكمن المشكلة في أن إعلان P/Invention الخاص بك لا يتطابق مع مكالمتك.يأخذ DeviceIoControl مؤشرات لمعلمات الدخول/الخروج:

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

لذلك يمكنك "تعديل" إعلانك بعدة طرق.يستخدم الرابط الموجود في الرابط الذي تقدمه ملف byte[] ربما من أجل الراحة حيث كانوا يستخدمونه.في حالتك، نظرًا لأنك تمرر بنيات بسيطة (أيلا توجد مؤشرات داخلية لبيانات أخرى)، فإن "الإصلاح" الأسهل هو مجرد تغيير إعلان P/Invoc:

[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/Invoc.على سبيل المثال، إطار الأجهزة الذكية يحتوي الكود على 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top