Как я могу передать структуру между .NET и C ++, используя COM? - PullRequest
3 голосов
/ 07 марта 2011

Я размещаю библиотеку .NET в моей программе на C ++, используя следующие методы, но не полный список:

CorBindToRuntimeEx()
GetDefaultDomain()
CreateInstance()
GetIDsOfNames()

И, в конечном итоге, вызов Invoke().

Это прекрасно работает для базовых типов, перечислений, строк и массивов.Тем не менее, я не могу понять, как передать структуру.Вот скелет того, что у меня сейчас:

//library.cs  
public class AStruct
{
    public int i1;
    public string s1;
    public double d1;
}  

//...
public AStruct getAStruct();

//interop.cpp  
HRESULT hr = assembly->Invoke (id_getAStruct, ...);

Возвращаемое значение OUT PARAM этой функции - VARIANT с типом VT_DISPATCH.

Когда я смотрю retVal.pdispValв моем отладчике я вижу, что содержимое моей структуры не близко к этому адресу.Я хотел бы использовать varIDis.pdispVal->QueryInterface() для доступа к моей структуре, но я понятия не имею, что такое IID, и как его обнаружить.

Кроме того, у меня нет исходного кода дляБиблиотека .NET, хотя я могу видеть многое из этого с помощью Reflector.Я использую тестовую библиотеку, написанную в .NET, чтобы понять, как действовать.

Итак, как я могу передавать и получать структуры между .NET и C ++ с помощью COM?

Большое спасибо.

1 Ответ

1 голос
/ 08 марта 2011

Я не думаю, что ваша проблема связана со структурами. На самом деле, здесь нет никаких структур - ни в C #, ни в C ++, ни в COM. Метод getAStruct (некоторого неопределенного класса?) Возвращает указатель на интерфейс IDispatch в экземпляре класса AStruct.

У вас недостаточно твердой информации, чтобы делать что-то правильно, поэтому я подхожу к этому ... (много догадок ...)

Забудь о структурах. Вы застряли с IDispatch *. Если вам известно полное определение класса AStruct или хотя бы полный список его свойств и порядок, в котором они определены, то начните с этого предположения: DISPID первого свойства - 0x6002000. Следующим является 0x6002001 и так далее. Конечно, это не гарантировано, но вам может повезти. И я забываю условия, из-за которых DISPID запускаются с 0x60020000, так что это может быть совершенно неверно. Кроме того, я не предполагаю, что есть какая-либо гарантия, что DISPID свойств идут в том же порядке, что и их определения в исходном коде.

Двигаясь быстро, вызовите IDispatch :: Invoke для полученного IDispatch *, передав угаданные DISPID и wFlags = DISPATCH_PROPERTYGET / PUT.

Как я уже сказал, много гаданий. Но если бы моя спина была у стены, я бы начал с этого.

...