Претоварвания в COM interop (CCW) - имената на IDispatch включват суфикс (_2, _3 и т.н.)

Имам управляван сборник, съдържащ няколко класа и тези класове имат претоварени методи. Излагам асемблирането на извикващите COM/IDispatch чрез

[ComVisible(true)]

..и също така задаване на правилното Ръководство, на самото събрание. Не дефинирам явен интерфейс за COM interop. Всичко се прави динамично. Пускам regasm.exe /codebase на управляваната DLL и тя я регистрира за COM interop.

Когато стартирам OleView, мога да видя ProgId на различните класове в сборката. Но, разглеждайки тези ProgIds и разширявайки IDispatch възел, няма информация за TypeLib за тези класове.

Дори и така, от скрипт мога да извикам метод, който приема нула аргументи, или метод, който приема един аргумент. Ако има и претоварване, което приема повече от един аргумент, не мога да извикам този метод по име. Грешката, която получавам постоянно, е

Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment:  <methodname>

От това разбрах, че клиентите на COM/IDispatch не са в състояние правилно да разрешат претоварени методи на обект, изложен чрез COM interop.


Тогава добавих

[ClassInterface(ClassInterfaceType.AutoDual)]

...на всеки от въпросните класове. След regasm.exe на DLL, мога да видя информация за typelib за всеки метод под възела IDispatch.

Това, което открих е, че претоварените методи автоматично получават име, което включва добавен суфикс. MethodX ще разкрие претоварванията в автоматично генерирания асембли на typelib като MethodX, MethodX_2, MethodX_3 и т.н.

И открих, че като се позовавам на имената на методите с тези суфикси, мога да извикам претоварени методи, макар и не с общото име.

По-интересното е, че ако след това премахна [ClassInterface(ClassInterfaceType.AutoDual)] от класовете, бих могъл все още да извикам претоварените методи по този начин, като по този начин избягвам грешката Wrong number of arguments or invalid property assignment.

Въпросът ми е: това поведение - добавяне на цифрови суфикси към имената на членовете - стабилно ли е? документиран? надежден?


person Cheeso    schedule 14.08.2009    source източник


Отговори (3)


COM не поддържа претоварване на метод, така че .NET COM Interop слоят трябва да импровизира. Не съм сигурен дали манипулирането на имена, както описахте, е документирано някъде, но дори и да е, не мисля, че използването му е добра идея - това все още е доста неудобен API за потребители на COM. Ако искате да изложите вашите класове на COM, най-добрият начин е да напишете отделен COM-удобен [ComVisible] интерфейс и да скриете самия клас. Правилният начин за справяне с претоварванията по COM-удобен начин би бил да имате един метод с някои [Optional] аргументи (и да делегирате на вашите съответни .NET претоварвания).

person Pavel Minaev    schedule 15.08.2009

Според моя опит взаимодействието генерира Method, Method_1, Method_2 и т.н. е нормално и стабилно, но не е много желателно. Досадно е, че претоварванията не преминават границата управлявано/неуправлявано. Вместо произволно да добавя цифров суфикс към моите методи, аз се опитвам да преработя COM-Visible методите в отделни методи с уникални имена, така че да е по-очевидно за потребителя на COM какво се извиква.

person C-Pound Guru    schedule 15.08.2009

Да, документиран е в MSDN:

Тъй като промяната му би била „чупеща промяна“ на документирана функция, предполагам, че можете да разчитате, че е „стабилна“. Големият недостатък е, че имената на вашите методи зависят от реда, в който са дефинирани в изходния файл.

Имайте предвид обаче, че COM поддържа незадължителни аргументи, така че използването им може да бъде жизнеспособна алтернатива на претоварванията. Ако трябва да добавите претоварвания, за да бъдете двоично съвместими със стари .NET клиенти на вашата библиотека, намерих следния модел за полезен:

// used for binary-compatibility with .NET clients who currently use 
// the old, one-parameter version
[ComVisible(false)]
void myMethod(String oneParameter) {   
    ... 
}   

// since this is the first COM-visible version, it is assigned the "correct" name.
void myMethod(String oneParameter, int newParameter = 0) {
    ...
}

Тъй като COM поддържа незадължителни параметри, и myMethod(string), и myMethod(string, int) ще работят.

person Heinzi    schedule 25.10.2012
comment
Забележка: Когато използвате VB.NET, тази техника (две претоварвания, различаващи се само по незадължителни параметри) изисква VS 2012. - person Heinzi; 21.11.2012