Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1394821001
MS-DOS user
2014-03-14 22:16
2014.10.26
Сервис int 21h/0Ah, шаблоны


2-1383659444
Дмитрий
2013-11-05 17:50
2014.10.26
Цвет фона TPageControl и TTabSheet


4-1269854506
QAZ
2010-03-29 13:21
2014.10.26
иконка по расширению


2-1383414170
Drowsy
2013-11-02 21:42
2014.10.26
После переустановки BDE.


2-1383653282
Dmitry.0xDEADFA11
2013-11-05 16:08
2014.10.26
Транзакции





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский