Форум: "Прочее";
Текущий архив: 2014.10.26;
Скачать: [xml.tar.bz2];
ВнизЧто будет если... Найти похожие ветки
← →
Dimka Maslov © (2014-03-14 14:20) [0]В некий код, написанный на сях (маздайных) передаётся указатель на интерфейс, реализованный на Delphi. Внутри сишного кода к указателю применяется dynamic_cast. Что произойдёт
а) Access Violation
б) dynamic_cast спокойно вернёт 0
в) всё будет зависеть от версий компиляторов
P.S. Сам смогу проверить только вечером, а думать уже сейчас надо.
← →
Inovet © (2014-03-14 14:26) [1]В Сях соответсвенно тоже будет реализован, так что должно быть NULL.
← →
Dimka Maslov © (2014-03-14 14:30) [2]В сях я спокойно могу проверить, реализован ли данный интерфейс через объект к.-л. класса, именно при помощи dynamic_cast. Вот я и думаю, а что произойдёт, если интерфейс будет реализован "на стороне". Мне надо что-то типа системы распознавания "свой-чужой" и не хочется во множестве объектов городить дополнительны интерфейсы, чтобы сделать это через QueryInterface
← →
Dimka Maslov © (2014-03-14 19:08) [3]Правильный ответ - Access Violation. Жаль. Придётся городить огород.
← →
clickmaker © (2014-03-14 19:27) [4]ну дык, dynamic_cast - это же часть RTTI, которую каждый язык может реализовать по-своему
← →
Rouse_ © (2014-03-14 19:31) [5]
> Dimka Maslov © (14.03.14 14:20)
> В некий код, написанный на сях (маздайных) передаётся указатель
> на интерфейс, реализованный на Delphi. Внутри сишного кода
> к указателю применяется dynamic_cast. Что произойдёт
Ничетак, а ты суров. VTable (VMT) ваще-то немного не стандартизированна. Даже в дружественном нам FPC первые 12 байт интерфейсной VMT заняты служебными полями, я уж не говорю за С++ где еще множественное наследование нужно учитывать.
← →
Dimka Maslov © (2014-03-14 19:33) [6]ну дык можно и проверку сделать перед тем как лезть в RTTI. Впрочем можно ещё сделать оболочку и ко всем "чужим" интерфейсам её применять.
← →
Dimka Maslov © (2014-03-14 19:35) [7]Или совсем уж дикий способ - таки позволять свершаться AV, перехватывать его и продолжать работу, как ни в чём не бывало...
← →
Rouse_ © (2014-03-14 19:41) [8]
> Dimka Maslov © (14.03.14 19:35) [7]
> Или совсем уж дикий способ - таки позволять свершаться AV,
> перехватывать его и продолжать работу, как ни в чём не
> бывало..
Один из наших "нанопрограммистов" уже уволенный давно, пытался найти ошибку в своем классе, в котором билась память. После полутора месяцев он добился того что смог все-же на AV и чтении определенного оффсета понять что память уже побилась. Решение проблемы тоже было изящное, как только он детектировал разрушение памяти он убивал экземпляр класса, ну а чтобы излишне не заморачиваться - в деструктор класса впихнул сразу конструктор самого себя.
Получилась эдакая "птица-феникс" возрождающаяся из пепла и не убиваемая ваще никаким образом из-за пресловутого конструктора в деструкторе.
Так что твой подход я одобряю - верной дорогой идешь :)
← →
Inovet © (2014-03-14 19:44) [9]> [3] Dimka Maslov © (14.03.14 19:08)
Так а dynamic_cast<К_Чему_Делается>?
← →
Dimka Maslov © (2014-03-14 22:54) [10]
> Inovet © (14.03.14 19:44) [9]
К указателю на интерфейс, полученный модулем, написанным на си, из модуля, написанного на delphi.
> Rouse_ © (14.03.14 19:41) [8]
Хитро, я бы до такого не додумался. Но в моём случае, я всё же сделаю так, что все объекты, реализованные в сишном модуле будут в своём QueryInterface на определённый guid откликаться, а в дельфийском - не будут.
← →
Игорь Шевченко © (2014-03-14 22:56) [11]COM-серверы, написанные на Delphi, спокойно реализуют всякие интерфейсы, которые передаются в код, написанный на произвольном языке.
Может, я не в тему, но слово вставить хочется.
← →
Inovet © (2014-03-14 23:10) [12]> [10] Dimka Maslov © (14.03.14 22:54)
> К указателю на интерфейс
Там Си не Builder случаем?
← →
Dimka Maslov © (2014-03-14 23:18) [13]
> Игорь Шевченко © (14.03.14 22:56) [11]
Знаю и давно этим пользуюсь для гибкого взаимодействия модулей различного происхождения, но возникла потребность отличать интерфейсы, реализованные в различных модулях.
> Inovet © (14.03.14 23:10) [12]
нет конечно
← →
clickmaker © (2014-03-15 12:48) [14]> [11] Игорь Шевченко © (14.03.14 22:56)
> COM-серверы, написанные на Delphi, спокойно реализуют всякие
> интерфейсы, которые передаются в код, написанный на произвольном
> языке.
ключевое слово здесь - "произвольный". dynamic_cast же - специфика плюсов
← →
Inovet © (2014-03-15 13:25) [15]Это получается есть нечто на Си++ и нечто с точно таким же функционалом на Делфи, и мы пытаемся кастить одно к другому. Ну... Тоже самое можно и без Си в Делфи сделать - закастим принудительно какой-нибудь TForm к TStringList, результат будет похожий.
Вообще, можно как-то с помощью магии попытаться повторить делфийскую огранизацию на Си. Только стоит ли оно того.
← →
Dimka Maslov © (2014-03-15 15:59) [16]
> Inovet © (15.03.14 13:25) [15]
Нет, кастить одно к другому не надо, а надо лишь п р о в е р и т ь, что полученный указатель на интерфейс реализован в модуле, разработанном на Delphi.
← →
clickmaker © (2014-03-15 16:22) [17]> [16] Dimka Maslov © (15.03.14 15:59)
а зачем? статистику собираешь? )
← →
bems © (2014-03-15 16:42) [18]
> надо лишь п р о в е р и т ь, что полученный указатель на
> интерфейс реализован в модуле, разработанном на Delphi
а) запросить у него ObjCastGUID: TGUID = "{CEDF24DE-80A4-447D-8C75-EB871DC121FD}" через QueryInterface
б) взять адрес реализации какого-нить метода IUnknown и загнать его в GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS or GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, ...)
← →
Dimka Maslov © (2014-03-15 18:30) [19]
> а зачем? статистику собираешь? )
Чтобы работать с ними по разному
← →
Dimka Maslov © (2014-03-15 18:33) [20]
> bems © (15.03.14 16:42) [18]
а) Это не работает с Delphi 2009. Но именно такой способ и видится мне единственно правильным, но только на некий guid должны будут откликаться "свои", а не чужие
б) даже если я получу hinstance некоторой dll, То как тогда определить, что он написан на Delphi?
← →
clickmaker © (2014-03-15 18:45) [21]> [19] Dimka Maslov © (15.03.14 18:30)
а что ж это за предметная область такая, где логика зависит от языка dll?
← →
Dimka Maslov © (2014-03-15 18:58) [22]
> а что ж это за предметная область такая, где логика зависит
> от языка dll?
Обработка исключений
← →
Игорь Шевченко © (2014-03-16 11:52) [23]У исполняемых файлов собранных на Delphi есть масса отличительных черт, например, ресурс с именем DVCLAL
← →
clickmaker © (2014-03-16 11:54) [24]у них еще с завидным постоянством версия линкера 2.25, наверно, еще с 3-ки или 4-ки. По крайней мере, для 32-бит
← →
icWasya © (2014-03-17 10:38) [25]Что произойдёт
а) Access Violation
б) dynamic_cast спокойно вернёт 0
в) всё будет зависеть от версий компиляторов
Это называется UB. То есть вариант в)
Чудес не бывает. Как будет работать dynamic_cast<A>(B)?
По некоторому смещению от B(которое зависит от компилятора и версии рантайма) считывается инвормация о типе, и сравнивается с A.
Если версия рантайма совпадает, то можно сделать однозначный вывод - является ли B наследником A. Если рантайм не совпадает, то даже при одинаковых компиляторах будет неправильный вывод.
Скорее всего "информация о типе" - это адрес таблицы виртуальных функций, который в DLL и в EXE будет разный.
← →
Romkin © (2014-03-17 11:34) [26]
> Dimka Maslov © (15.03.14 18:58) [22]
> > а что ж это за предметная область такая, где логика зависит
> > от языка dll?
> Обработка исключений
Кхм. COM реализует языконезависимую обработку исключений, которую и надо использовать, а не городить свой огород.
← →
Dimka Maslov © (2014-03-17 18:55) [27]
> icWasya © (17.03.14 10:38) [25]
Выкатывается AV. Я проверял.
> Romkin © (17.03.14 11:34) [26]
Про safecall я в курсе, но не использую СOM, у меня интерфейс - лишь абстрактный класс, указателями на объекты которого обмениваются различные части программы в рамках одного процесса. И исключения прекрасно передаются из модуля в модуль, даже при перекрёстных взаимных вызовах и спокойно отлавливаются. Единственное, что сделать нельзя - это определить тип исключения, возникшего в модуле, написанном на другом языке и выдать пользователю осмысленное сообщение. Целенаправленно городить у себя весь COM c его кучей ненужных в данном случае вещей - только снижать производительность и засорять систему.
← →
bems © (2014-03-17 22:05) [28]
> Единственное, что сделать нельзя - это определить тип исключения,
> возникшего в модуле, написанном на другом языке и выдать
> пользователю осмысленное сообщение
ну можно проанализировать ExceptionCode на предмет совпадения с cDelphiException, и что там еще определено в system.pas
← →
bems © (2014-03-17 22:14) [29]ну или сравнивать с кодом от ms 0xe06d7363
← →
Dimka Maslov © (2014-03-17 22:38) [30]
> bems © (17.03.14 22:14) [29]
Пишется класс-облочка для интерфейса, в деструкторе которого определяется что а) произошло исключение б) интерфейс реализован на Delphi затем идёт запрос в дельфийский модуль "брателло, ты тут это исключеньицами кидаешся, а не объяснишь ли мне, чё там у тебя не того", на что дельфийский модуль отвечает содержимым ExceptObject. Потом дельфийское исключение перехватывается через catch(...) и бросается уже как родное сишное.
← →
Romkin © (2014-03-18 12:58) [31]
> Единственное, что сделать нельзя - это определить тип исключения,
> возникшего в модуле, написанном на другом языке и выдать
> пользователю осмысленное сообщение. Целенаправленно городить
> у себя весь COM c его кучей ненужных в данном случае вещей
> - только снижать производительность и засорять систему.
safecall - это не COM. Не хочешь использовать уже имеющееся - ничто не мешает сделать аналог ISupportErrorInfo и использовать.
← →
bems © (2014-03-18 12:59) [32]
> Dimka Maslov © (17.03.14 22:38) [30]
ну а я тебе предлагаю не анализировать при вызове чего произошел эксцепшн, а анализировать сам эксцепшн
или как вариант в каждом (на любом языке) модуле сделать экспортируемую функцию, которая отвечает на вопрос "а не объяснишь ли мне, чё там у тебя не того". в каждом модуле эта функция имеет одинаковое имя. определяешь модуль, реализующий интерфейс и вызываешь функцию с таким именем из этого модуля
← →
Romkin © (2014-03-18 13:14) [33]Если под "модулем" понимается dll, то передача исключений за границы модуля чревата внезапностями с памятью.
http://www.gunsmoker.ru/2012/02/5.html#n4
← →
Dimka Maslov © (2014-03-18 14:38) [34]
> bems © (18.03.14 12:59) [32]
Все исключения у меня генерируются и обрабатываются в одном модуле (назовём его центральным). Поэтому всё прекрасно работает. Другое дело, что дельфийский код может ненароком поднять своё исключение - вот тогда, хоть оно и перехватывается (нормально перехватывается и ничего никуда не утекает - fastmm стоит на страже), но нет возможности выдать нормального вида сообщение - вот тут и надо опрашивать модуль на предмет произошедшего, проблема не в том, как опрашивать, а когда надо опрашивать.
← →
bems © (2014-03-18 16:53) [35]
> Dimka Maslov © (18.03.14 14:38) [34]
я же это и говорю. лан, не нравятся предложения - думай сам
← →
icWasya © (2014-03-18 17:48) [36]Если это COM, то в Дельфи методы скорее всего описаны как SafeCall - они не должны выбрасывать исключения.
← →
Dimka Maslov © (2014-03-18 19:45) [37]
> icWasya © (18.03.14 17:48) [36]
Это я всё написал, и методы описаны как stdcall, мне важнее производительность, а не постоянная проверка кода ошибки
← →
Inovet © (2014-03-18 21:23) [38]Тогда я бы сходил по указателю и поискал специфические для каждого языка структуры. Т.е. кастить надо к указателю на байт.
← →
Dimka Maslov © (2014-03-19 21:52) [39]Сделал так: каждый объект должен реализовавать некоторый интерфейс IModuleRequest c одним методом GetModule, который возвращает hInstance своего модуля. Если интерфейс не реализован, или возвращает hInstance другого модуля, он считается "чужим" и к нему применяются все рестрикции. Да, в силу того, что в убогоих сях нельзя наследовать реализацию интерфейсов родительского объекта (большое спасиюо Борланду за TInterfacedObject и наше счастливое детство) это потребует написания долполнительного кода, но все способы с "хождениями по указателям" кажутся мне ненадёжными или зависящими от версии среды разработки.
← →
jack128_ (2014-03-19 22:17) [40]
> нельзя наследовать реализацию интерфейсов родительского
> объекта
э-э-э. В смысле?? На дельфи можешь описать что ты имеешь в виду?
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2014.10.26;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.002 c