PInvoke не работает в определении класса - PullRequest
2 голосов
/ 19 марта 2012

У меня проблема, странная.Когда я использую следующую структуру в PInvoke, она работает, но когда я изменяю ее на класс, она не работает.

мой c #:

[StructLayout(LayoutKind.Sequential)]
public struct SPInvokeImage
{          
    public int m_BitsPerPixel;  // 8,16,24,32 
    public int m_ImageHeight;
    public int m_ImageWidth;
    public int m_BytesArraySize; // array size in bytes. 

    public IntPtr m_pArray; //data array 
}

c ++

   typedef struct 
   {          
 int mBitsPerPixel;  // 8,16,24,32 
 int mImageHeight;
 int mImageWidth;
 int BytesArraySize; // array size in bytes. 

 uint8_t *Array;        //data array 
   }SPInvokeImage;

, когда я изменяю c # на это, он перестает работать:

 [StructLayout(LayoutKind.Sequential)]
 public class SPInvokeImage
 {          
     public int m_BitsPerPixel;  // 8,16,24,32 
     public int m_ImageHeight;
     public int m_ImageWidth;
     public int m_BytesArraySize; // array size in bytes. 

     public IntPtr m_pArray; //data array 
 }

Ответы [ 2 ]

2 голосов
/ 19 марта 2012

Структуры являются типами значений, а классы являются ссылочными типами. Правила передачи этих двух типов в вызов метода P / Invoke различны.

Есть ли конкретная причина, по которой вы хотите использовать класс, когда структура работает нормально? Вам явно нужна семантика типа значения, поэтому используйте тип значения, чтобы получить их.

Если вам действительно нужно сделать класс по какой-то причине, мне нужно увидеть сигнатуру метода, который вы вызываете, чтобы увидеть, что происходит не так. Скорее всего, у вас есть ref, прикрепленный к тому месту, к которому он не принадлежит.

РЕДАКТИРОВАТЬ: на основе вашего комментария о нулевых указателей:

Использование класса - это один из вариантов, просто убедитесь, что вы не передаете его явно ref, поскольку это происходит автоматически. Другой вариант - использовать IntPtr и передать либо IntPtr.Zero для нулевого значения, либо результат Marshal.StructureToPtr для реального значения.

2 голосов
/ 19 марта 2012

Это потому, что когда вы переключаетесь на класс, объект передается в нативный код по ссылке, а не по значению, как для struct. Так что есть дополнительный уровень косвенности. Вам нужно будет удалить этот уровень косвенности в вашей декларации pinvoke. Вы, вероятно, проходите, используя ref в данный момент. Просто удалите ref при переключении с struct на class.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...