Устранение проблемы, связанной с маршалингом x64 com interop - PullRequest
1 голос
/ 03 ноября 2010

У меня есть C ++ COM-сервер, который я недавно перекомпилировал на 64-битный.Этот COM-сервер имеет метод, который содержит параметр структуры, который содержит некоторые целые, BSTR и другую структуру.Теперь я пытаюсь вызвать этот COM-сервер из 64-разрядного приложения .Net C #.Я могу успешно загрузить свой COM-сервер и вызвать этот метод, если не пытаюсь заполнить ни один из строковых параметров.Если я попытаюсь передать допустимые значения в члены int, они будут повреждены к тому времени, когда они завершатся реализацией COM-объекта.Создается впечатление, что способ маршалинга структуры просто неправильный.Этот код прекрасно работал в 32-битных приложениях.

Ниже приводится общий способ определения idl на стороне C ++: (игнорируйте глупые определения типов, это какой-то устаревший код)

[helpstring("method Method1")] HRESULT Method1([in] STRUCT1* pStruct, [in, out] DWORD* inparm1, [out]USHORT* outparm2);


typedef struct _Struct2
{
    USHORT  p1;
    BSTR  s1;
    BSTR  s2;
    BSTR  s3;
    BSTR  s4;
    DWORD       p2;
    DWORD       p3;
} STRUCT2;


typedef struct _Struct1
{
    DWORD p1;
    DWORD p2;
    BSTR s1;
    BOOL p3;
    STRUCT2 struct2;
}STRUCT1;

Попытка заполнить членов в STRUCT2 приводит к неопределенному поведению и сбоям.Может кто-нибудь понять, почему это было бы проблемой в 64-разрядных стихах 32-разрядного кода?Есть ли какая-нибудь маршальная магия, которая мне нужна?Кроме того, у меня, похоже, нет инструментов для устранения проблем с маршалингом.Какие-нибудь предложения относительно хорошего способа устранения проблем, что маршалер делает под прикрытиями?

1 Ответ

2 голосов
/ 03 ноября 2010

Структура - это Ахиллесова пята COM. Фактическое расположение членов структуры сильно зависит от компилятора. Они не были поддержаны в автоматизации COM в течение достаточно долгого времени, пока они не придумали взломать IRecordInfo. Не привыкаешь здесь.

В неуправляемом коде очень важна директива #pragma pack. Для библиотек типов необходим аргумент / pack для midl.exe. Если это не 8 или вы не используете 64-битную версию midl, то у вас точно будут проблемы такого рода. Члены BSTR - это те, которые его отбрасывают, это либо 32-битные, либо 64-битные указатели, в зависимости от битности. Выровняйте по кратному 4 для 32-битной версии midl, кратному 8 для 64-битной версии. Вы можете спасти его, передав / pack 4, если в структуре нет двойников. Но сначала попробуйте 64-битную версию midl.exe. Или избавьтесь от структур и замените их указателями интерфейса, это реальное исправление.

...