Более чистый способ написания кода вместо Marshall.QueryInterface? - PullRequest
1 голос
/ 28 сентября 2010

Мне интересно, есть ли более чистый способ написать ( рабочий ) код ниже:

uint uEnum = 0;
PStore.EnumTypes(0, 0, ref uEnum);
System.Reflection.MemberInfo inf = typeof(PSTORECLib.CEnumTypes);
GuidAttribute CEnumGuid = 
    (GuidAttribute)inf.GetCustomAttributes(typeof(GuidAttribute), false)[0];
Guid tmp = new Guid(CEnumGuid.Value);
IntPtr ppv;
Marshal.QueryInterface((IntPtr)uEnum, ref tmp, out ppv);
PSTORECLib.CEnumTypes EnumPStoreTypes = 
    (PSTORECLib.CEnumTypes)Marshal.GetObjectForIUnknown(ppv);

//Later
Marshal.Release(ppv);

Когда я попытался вставить IEnumPStoreTypes** в idl-файл PSTORECLib (т. Е. Когда я использовал исходный IDL-вывод oleview) в вызов PStore.EnumTypes, dll-вывод tlbimp сказал мне передать ссылку на CEnumTypes. Функция была довольна этим (вернула S_OK), но не заполнила ссылку. Этот беспорядок в уродливом коде произошел, когда я изменил его, чтобы вместо него принять указатель на long, и сделал то, что я сделал, чтобы экземпляр CEnumTypes ссылался на указатель. Все это кажется мне немного грязным, хотя оно работает . Есть ли более чистый способ сделать это?

Обратите внимание, что строка PSTORECLib.CEnumTypes cen = new PSTORECLib.CEnumTypes(); вызовет исключение COMException "Class Not Registered".

Ответы [ 2 ]

4 голосов
/ 28 сентября 2010

Ой, вы взламываете COM низкоуровневым способом. Это примерно нормально, но есть проблемы. Он никогда не будет работать в 64-битном режиме, uEnum не может быть uint, это должен быть указатель. Это также утечка, вы не вызываете Release () для этого. Вы не можете игнорировать это.

Очевидно, что у вас есть библиотека типов и вы создали из нее библиотеку взаимодействия, иначе код отражения не будет работать. Я могу только догадываться, что с IDL что-то не так. Подпись EnumTypes предполагает, что вы забыли атрибуты [out, retval] в последнем аргументе. По крайней мере, опубликовать IDL для EnumTypes.

0 голосов
/ 28 сентября 2010

Я начал редактировать свой пост, чтобы предоставить информацию, которую просил Ганс Пассант, затем я получил прозрение и выяснил проблему.По какой-то причине и у старой версии библиотеки типов, созданной предыдущим человеком, работавшим над этим проектом, и у меня была похожая проблема, вероятно, потому что мы оба доверяли oleview больше, чем следовало.из параметров был параметр [in] вместо параметра [out].VB6 не волновало, но C # очень заботился.

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