PInvoke адресация - PullRequest
       11

PInvoke адресация

0 голосов
/ 09 февраля 2012

У меня есть метод в C ++ с двумя аргументами: byte и ushort, который возвращает указатель на очень сложную структуру (это объединение почти всех структур, представленных в проекте C ++).

Когда я вызываю этот метод, используя DllImport в C #, например, передавая ему 1 и 2, он вызывается с некоторым случайным числом байтов и 1 (поэтому первый аргумент передается как второй, а действительное первое берется из некоторого другого адрес памяти).

Единственное объяснение, которое я могу придумать, о том, что возвращаемая структура не отображается правильно, и из-за этого все параметры имеют смещение. Но я не знаю, как это проверить. Существуют ли какие-либо инструменты, которые могут показывать мне адреса и размеры маршаллированных данных, генерируемых C #, поэтому я могу проверить их по адресу, который я получаю в C ++? Или любое другое решение, которое вы можете предложить.

--- Обновление ---

После комментирования структур кода для C ++ и C # я сократил тестовый код до следующего: C ++:

enum PrimitiveType: unsigned short
enum ErrorType : unsigned char 

typedef struct
{
  PrimitiveType Primitive;
  unsigned char InstNo;       /* The instance number. */
  ErrorType ErrorCode;         /* ERR_NO_ERROR */
  unsigned char Active;                      /* True = relay active */
 } GetRelayCfmType;

sizeof (GetRelayCfmType) = 5

C #:

enum PrimitiveType : ushort
enum ErrorType : byte

    [StructLayout(LayoutKind.Sequential)]
    public struct GetRelayCfmType
    {
        public PrimitiveType Primitive;
        public byte InstNo;                         /* The instance number. */
        public ErrorType ErrorCode;          /* RTX2300_ERR_NO_ERROR */
        public byte Active;                      /* True = relay active */
    };

Marshal.Sizeof (new GetRelayCfmType ()) == 6.

Почему размеры отличаются одним байтом? Upd.

Теперь моя функция (C ++):

__declspec(dllexport) GetRelayCfmType __stdcall GetRelay_Blocking(unsigned char InstNo, RelayNoType No)

 enum RelayNoType : unsigned char

так в C # у меня есть:

[DllImport(DLL_NAME, CallingConvention = CallingConvention.StdCall)] 
    public static extern GetRelayCfmType GetRelay_Blocking(byte InstNo, RelayNoType No);

enum RelayNoType : byte

Теперь картинка заполнена.

1 Ответ

0 голосов
/ 09 февраля 2012

Вам явно нужна дополнительная информация, прежде чем вы запросите нашу помощь. Взгляните на эту статью: http://msdn.microsoft.com/en-us/library/eahchzkf(v=vs.100).aspx обратите внимание на сделанное заявление.

Хотя вы можете использовать метод Marshal.SizeOf, значение, возвращаемое этот метод не всегда совпадает со значением, возвращаемым sizeof. Marshal.SizeOf возвращает размер после того, как тип был маршалирован, в то время как sizeof возвращает размер, как он был выделен общим время выполнения языка, включая любые отступы.

Я подозреваю, что это из-за заполнения внутри структуры. Вы позволили .NET Последовательное расположение структуры. Это, конечно, позволяет угадывать определенные вещи. Я бы использовал Явный , установил Пакет и, возможно, даже Размер .

...