Page 1 of 1
И как всё-таки получить интерфейс на С++?
Posted: 31 Oct 2006, 16:29 Tue
by ukc
Т.е. ума не приложу, как должна выглядеть сигнатура функций?
Представленные в api объявления совсем не похожи на COM, как их правильно сконвертировать?
Методом тыка (пытаясь загрузить плагин плагин планировщика) нашел сигнатуру для экспортируемой функции
Code: Select all
HRESULT _stdcall RegisterPlugIn (IDMPlugIn**);
Т.е. возвращает значение функция всё же в один из своих параметров.
AddRef и Release у полученного интерфейса вызываются, по крайней мере, без проблем =). Но как быть с другими?
Подскажите, хотя бы, доку по реализации делфёй разных соглашений о вызове, а?
~~~~~~~~~~~~~~~Чуть позже~~~~~~~~~~~~~~~~~~~~
Доку нашел
Есть успехи. Блин, оказывается указатель (ссылка) на место, в которое нужно записать Result передается ДО указателя (ссылки) на интерфейс, что всяко противоречит принятым в C++ соглашениям. Интерфейс будет (если не обхарит) на C. Надо кому?
Posted: 01 Nov 2006, 18:39 Wed
by ukc
Очень хочется попросить разработчиков прислушаться к этим советам, при разработке новых API:
Расскажу об опыте практической реализации связки приложений на Delphi и С++.
Оказывается не все так просто, как кажется на первый взгляд.
Существует ряд неписанных правил, которые нигде не оговорены, но без их соблюдения диалог разноязыковых программ невозможен.
1)
Нельзя писать следующее объявление метода интерфейса:
function GetItem: IMyItem; stdcall;
Писать необходимо так:
procedure GetItem(out AItem: IMyItem); stdcall;
Эта проблема возникает от того, что Delphi проталкивает в стек указатель на интерфейс и вызывает функцию. Тогда как С++ не берет указатель из стека и не меняет его значение, а возвращает указатель на интерфейс в регистре EAX.
По правилам вызовов stdcall C++ прав. Но так или иначе ни структуры (record в паскале) ни интерфейсы нельзя передовать как результат функции.
2)
Нельзя писать следующее объявление метода интерфейса:
procedure GetItem(var AItem: IMyItem); stdcall;
Писать необходимо так:
procedure GetItem(out AItem: IMyItem); stdcall;
Именно out, а не var, так как С++ ничего не инициализирует и в указателе на переменную AItem может быть мусор, а Delphi обязательно попытается вызвать у мусора Release, чем и вызовет сбой программы.
Может это и не все причуды реализации COM, но рассказал про то с чем имел дело.
Слава
Про причину проблемы автор немного напутал (проблема в том, что следом за проталкиванием в стек указателя на интерфейс, делфи заталкивает туда адрес указателя на результат (которого именно там быть не должно)).
Второе обходится аккуратным программированием плагина. Но зачем усложнять.
Есть пример написания плагина в MSVS/VC8 (всё-же на С++). Если кому нужен - велкам в приват или аську.
Posted: 02 Nov 2006, 7:34 Thu
by Атех
ukc wrote:
Есть пример написания плагина в MSVS/VC8 (всё-же на С++). Если кому нужен - велкам в приват или аську.
Опубликуйте пример прямо здесь, если Вам не сложно.
Posted: 02 Nov 2006, 13:36 Thu
by ukc
Posted: 10 Nov 2006, 20:22 Fri
by -=Vd=-
Спасибо, сам ковырял - ничего не получилось. Попробую заюзать.
Posted: 21 Jun 2007, 20:42 Thu
by aldari
Спасибо I like C++ :D :lol: 8) :D :)
Posted: 21 Jun 2007, 23:10 Thu
by aldari
Может быть усилием воли в версии 3.5 поправить интерфейс плагинов.
А код на С++ обязательно нужно выложить рядом с Delphi.
Правда в без поправок он несколько больше Delphi, что и понятно.
Posted: 30 Oct 2008, 4:42 Thu
by JPooh
если у кого есть, выложите пример плагина на C++ пжалста,
ссылка товарисча ukc к сожалению сдохла.
лучше всего для BCB6... но пойдет и для VC конечно.
Posted: 12 Nov 2008, 20:33 Wed
by Alex Qwerty
Posted: 18 Nov 2008, 2:44 Tue
by JPooh
Премного вам благодарен, уважаемый Alex-гуру.
