Здравствуйте, ·, Вы писали:
·>Из наиболее развитых. Сравнивать QT Creator с MSVS... Даже Delphi и то были мощнее чисто-С++ IDE (по крайней мере мне известных). А так я и на бейсике IDE напишу.
А ты их сам сравнивал? ) Я вот сравнивал и MSVS и Eclipse и Netbeans и QtCreator. MSVC кстати весьма слабенький для C++, если не пользоваться VisualAssist'ом (отдельная платная штука). Eclipse и Netbeans весьма похожи между собой по возможностям и при этом существенно отличаются от того же QtCreator. У них используется модель полного анализа кода, которая позволяет такую возможность как подчёркивать невалидный код до компиляции и т.п.. Но цена у этого жуткие тормоза. Ну точнее если работать только с ними, то постепенно привыкаешь к тормознутости IDE... Но если вдруг при этом включить QtCreator, то такое впечатление что он просто мгновенный. Но при этом он делает не полный анализ кода... В принципе выбор между этими продуктами является делом вкуса. Но говорить о явном преимуществ какой-то из них странно.
Кстати, недавно одному моему товарищу, работающему в основном в мире Java, потребовалось сделать приложение с GUI на C++. Он взял библиотеку Qt (по моему совету) и соответственно QtCreator в качестве IDE (ради удобного встроенного редактора форм/сигналов и т.п.). Так вот он был в полном восторге (особенно от всяческих автоматических компоновщиков и их поддержке в редакторе, управлением сигналами и т.п.) от этого инструмента (накидал довольно сложный GUI за несколько дней), причём во многом он удивлялся что так вообще можно (в своём java мире он такого не встречал).
Здравствуйте, ·, Вы писали:
_>>Undefined behaviour это по стандарту языка, без учёта работы ОС. Ну т.е. да, для каких-нибудь микроконтроллеров там действительно будет порча памяти, но на этих МК такие вещи как Java/C# вообще не живут. А в любой современной ОС мы получим соответствующее исключение. ·>Т.е. ты даже в двух строчках кода забыл "x=nullptr"... А в случае более-менее сложного кода, да ещё и многопоточного — только в путь.
Ну так у меня же мало практики в написание заведомо некорректного кода. Я вообще сам delete раз год вижу, даже с корректным кодом. А тут такое... )))
_>>P.S. Ну и да, не забываем, что это мы тут развлекаемся обсуждением заведомо некорректного кода. ))) Типа а вот если мы специально подставим компилятор вот так, то в каком языке какие ошибки будут... ))) В реальном коде такое естественно не встречается. ·>И ты правда не видел битых указателях в реальных проектах? Укажи, плиз, номер твоей планеты в тентуре.
Здравствуйте, ·, Вы писали:
_>>Дефолтное — это value type и контейнеры stl. Есть парочка редких случаев, когда применение этих инструментов приводит к не самому оптимальному кода (и тогда как раз делают всяческие кастомные аллокаторы и т.п.), но лично я на них натыкался исключительно в обсуждениях на форумах и т.п., а не в личной практике. ·>В дефолтном случае и GC замечательно работает. А вот эти обсуждаемые извращения в Яве это и есть те самые редкие случаи.
Нет, это как раз совсем разные случаи. Единственный сценарий, на котором GC начинает конкурировать с обычной работой с памятью в C++ — это режим создания/удаления множества мелких объектов в куче. Так вот этот режим в C++ встречается на очень редком классе задач (и для них уже есть смысл рассматривать спец. аллокаторы и т.п.). И задачи типа реалтайма или высокой нагрузки точно не относятся к этому исключению — там как раз эффективны стандартные техники C++.
В то же время в Java режим создания/удаления множества мелких объектов в куче — это норма. И хотя GC не так плохо справляется тут, но он намного отстаёт от C++ на большинстве задач, т.к. в C++ в этих случаях используется другой режим (который априори быстрее). И только в том случае, когда и в C++ необходимо плодить сущности типа shared_ptr, быстродействие может сравниться (при условие, что в C++ не будем вводить кастомные извращения).
Соответственно, чтобы догнать C++ на задачах реалтайма, высокой нагрузки и т.п. (в остальных областях тоже медленно, но всем просто пофиг) в Java переходят от дефолтного режима на некое извращение с рукопашными буферами и т.п. ужасами для эмуляции стандартных техник C++.
Т.е. главный нюанс в том, что хотя в обоих языках есть области, требующие неких нестандартных для языка подходов, эти области совершенно разные у данных языков. И размеры этих областей тоже принципиально разные.
_>>·>А ты часто обдумываешь в какие регистры процессора какая переменная попадёт? _>>Совершенно не обдумываю, причём по разным причинам в двух разных случаях. В случае отсутствия необходимости в быстродействие (кстати в этом случае у меня скорее Питон в руках будет) понятно что не обдумываю потому что безразлично. А в случае необходимости высокого быстродействия и использования C++ тоже не обдумываю, потому как знаю, что оптимизатор современных компиляторов C++ создаст код лучше любого эксперта в ассемблере. ·>Собственно та же ситуация и с GC.
Абсолютно не такая же. Напомню, что мы здесь обсуждали возможности JIT выбрать расположение и типы данных (куча/стек, ссылка/значение и т.д.) наиболее оптимальным способом. И в отличие от качества генерирования ассемблерного кода оптимизаторами C++, тут ситуация даже не приблизилась к идеалу. И я сомневаюсь что приблизится когда-нибудь, т.к. тут задача намного сложнее.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>Ты в этом примере демонстрируешь вообще другое. Возможность вызова .net кода из 1C. Ну так понятно что с этим нет проблем, если в 1C это специально предусмотрели. И с другими языками/платформами может быть аналогично. Непонятно что ты этим хотел показать. S>> Нет это не в 1С предусмотрели, а в Net. http://infostart.ru/public/238584/ S>>А вот теперь покажи как можно использовать классы С++ раз это можно сделать аналогично. S>>Я к тому, что написать код аналогично 1С на C# нет проблем.
_>Аааа, так оно ещё и через COM это делается... ) Тогда уж точно никакой разницы с другими языками нет, причём уже прямо сейчас. Т.е. банально реализуем соответствующий COM интерфейс и без проблем используем его в 1C. Не знаю правда зачем, но делается это тривиально. )))
Тебе нужно делать обертку Idispatch над объектом, типом. В Net это делается через Reflection к любому типу, объекту
Раз это элементарно забацайка. В той статье класс оборачивает любой объект, тип. Поддержка энумераторов.
Давай прямо сейчас.
Это еще раз подтверждение того, что ты невнимательно читаешь ссылки
Что было понятно то основной метод такой обертки для вызова свойства метода реального объекта.
public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
{ // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)if (name == "[DISPID=-4]")
{
return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
}
object[] args = ПолучитьМассивРеальныхОбъектов(argsOrig);
culture = CultureInfo.InvariantCulture;
// Invoke whatever needs be invoked!object obj;
try
{
if (T.IsEnum && !((invokeAttr & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod))
return ОбернутьОбъект(Enum.Parse(T, name));
// if (ЭтоСемерка)
ПроверитьНаДоступКПолям(ref invokeAttr, args.Length);
if (ЭтоТип)
obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
else
obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
}
catch (Exception e)
{
ПоследняяОшибка = e;
string Ошибка = "Ошибка в методе " + name + " " + e.Message + " " + e.Source;
if (e.InnerException != null)
Ошибка = Ошибка + "\r\n" + e.InnerException.ToString();
if (ВыводитьСообщениеОбОшибке)
{
MessageBox.Show(Ошибка);
MessageBox.Show(e.StackTrace);
MessageBox.Show(invokeAttr.ToString());
}
throw new COMException(Ошибка);
}
// Так как параметры могут изменяться (OUT) и передаются по ссылке
// нужно обратно обернуть параметры
УстановитьИзмененияВМассиве(argsOrig, args);
return ОбернутьОбъект(obj);
}
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, ·, Вы писали:
_>>Лично я не увидел в этом списке чего-то необычного, заставившего писать непривычный код. ·>А тебе вообще доводилось писать LL код?
Я же тебе уже даже примеры приводил. ) И да, оно не из области финансов. )))
_>>Рассуждения без аргументов не интересны. А если попробовать взглянуть на реальность, то "неожиданно" обнаруживается, что почти все самые сложные современные приложения написаны на C/C++. Причём не только системные, типа ОС, но самые пользовательские, типа браузеров. ·>В ФФ бОльшая пользовательская часть это js, xul и прочее. А вообще браузер системная вещь — основное назначение — взаимодействие с железом и ОС. Не путай с прикладными приложениями, типа очередной бухгалтерии или склада.
Да, написание приложения на C++ со встроенным скриптовым языком — это стандартная техника написания сложных и эффективных приложений. Это не только браузеры, но и тяжёлые игры и всякий профессиональный софт (CAD'ы, редакторы/рендереры и т.п.)и ещё много где. Проще вспомнить где такого нет. ))) Кстати, мы такое тоже используем.
Да, и браузер — это совсем не системный софт (с каких это пор взаимодействие с ОС стало признаком системного софта?), т.к. работает на обычном пользовательском уровне. Системный софт — это всяческие драйверы, сервисы и т.п. )
_>>Так а зачем я тогда буду делать такой MaClass? ))) Кстати, куча полей — это сколько? ) Ты в курсе размера линии кэша современных процессоров? ) ·>"Дефолтное — это value type и контейнеры stl" и даст тебе тот самый жирный MyClass. ·>Кеш в районе всего лишь нескольких мегабайт — копейки же, миллиончик элементов — и упс, кончилось.
Хыхы, в данном случае важнее размер не всего кэша, а именно его линий (в соотношение с размером самого объекта). А так же очевидная для предсказателя последовательность выборки.
Здравствуйте, ·, Вы писали:
dot>>>Не сможет — чуть тормозить начнёт. А если человек не сможет доказать передачу указателей — всё круто и непредсказуемо навернётся. EP>>А зачем человеку доказывать? Например: EP>>Результат может содержать ссылку на этот unique, а может не содержать. Человек может например просто знать из документации что в результирующем объекте нет этого unique. dot>Тут мне кто-то рассказывал, что надо голые указатели использовать при передаче между потоками.
Для не владеющих указателей — да. Здесь речь идёт про владеющий. Да и к чему ты тему переводишь?
EP>>Анализатору же придётся это доказывать проинлайнив весь код. dot>Да пусть доказывает, он железный, зарплату не просит.
У него есть жёсткие ограничения по бюджету времени — так как работает у конечных пользователей.
EP>>>>Это типичный миф обитающий в среде Java/C# — мол на каждый наш new, будет какой-нибудь *_ptr в C++. dot>>>... либо битый указатель. EP>>*_ptr не спасают от битых указателей, их основанная цель это выражение семантики владения в коде, отсюда и имена shared/unique/scoped. dot>Как более безопасный подход — оно вроде работает. Если ты будешь использовать в коде _ptr а не * и &, то нарваться на битый указатель практически невозможно.
Никто не использует *_ptr везде, даже в самых запущенных случаях.
EP>>Это изменение контракта, которое прекрасно выражается в системе типов — у doSomething поменяется тип параметра и приведённый код не скомпилируется dot>Поменяется с чего на что? как было (Widget &w) так и останется, если не лепить _ptr на каждый чих.
Теперь ей требуется владение — так как есть передача куда-то что может жить дольше caller'а. Вот тут как раз будет либо *_ptr, либо например rv ref — и то и другое приведёт к ошибке компиляции в старом клиентском коде
EP>>>>Выходим из scope — дальше какие действия? Какое преимущество даст EA в этом случае? dot>>>Тем что объект пойдёт на стек или в регистры. Какие аллокации? EP>>Ещё раз. Прочитай свои слова выше (выделено), и ниже: EP>>
dot>>>Перенос объекта на стек это другая оптимизация. Может делаться только для маленьких оъбектов. Если у тебя выделяется 100мб массив и EA покажет, что ссылка на массив не убегает за пределы, то при выходе из стека объект грохнется. Т.е. по сути тот же unique_ptr.
EP>>Теперь скажи каким образом здесь поможет EA. dot>Что-то я тут фигню какую-то написал. Ссылка на стеке, конечно, как и unique_ptr, а сам массив в куче, как и unique_ptr, при выходе из стека — пропадёт ссылка.
При выходе из стека корневая ссылка пропала бы и без EA.
dot>При сборке Eden Space оно и грохнется,
Оно бы грохнулось в тот же самый момент и без EA.
dot>не совсем при выходе из стека, но очень близко.
То есть совсем не при выходе из стэка.
dot>А если ты чуть поменяешь код и ссылка будет отправлена куда-то ещё, другому треду, попадёт в какой-нибудь контейнер, кеш, етс, то ничего не поломается, в отличие от unique_ptr.
У него тоже ничего не поломается. Даже если бы это был просто vector<T>, без unique_ptr — то тоже ничего бы не поломалось
dot>>>Указатель ещё тип имеет. Ссылка в яве тоже адрес хранит и чё. EP>>Конечно, и в типе разница — на C++ можно иметь указатель на элемент массива, на Java — нет. dot>Ты так говоришь, как будто это что-то плохое.
Это очевидный недостаток. Например есть текст, нужно передать куда-то отдельный абзац — на C++ достаточно например либо двух указателей, либо указателя и числа символов, либо просто указателя на начало абзаца. На Java же придётся ещё таскать ссылку на сам текст.
EP>>>>>>Не грохнется — у него нет зависимости O(N) от количества живых объектов. dot>>>>>new/malloc и delete/free работают не за O(1) внезапно. EP>>>>Например для Buddy Allocation сложность логарифмическая. Есть же в том числе и O(1) алгоритмы, например TLSF. dot>>>Так и разные алгоритмы GC есть. И столько всего можно крутить... И я уверен, что вариантов даже больше, ибо ссылка в jvm более абстрактна чем указатели в плюсах, а значит больше простора для оптимизаций. EP>>Так вот покажи GC не с сублинейной сложностью, желательно ещё чтобы был более-менее популярен. dot>Если вдруг GC начинает работать в режиме, что его сложность становится O(N) — ты делаешь что-то не то, тебе надо крутить настройки или даже изменять код.
Нет гарантии что она завтра вдруг не выстрелит
dot>>>>>Quick-sort имеет сложность O(N*N), как и пузырьковая... но это ещё ничего не значит. EP>>>>Конечно значит, именно поэтому в реализациях std::sort используется introsort, которая хоть и основана на quicksort, но выдаёт линеаритмическую сложность dot>>>Да, неудачный пример. Лучше рассмотреть hashtable. Сложность O(n). и что? Просто крутят использование до тех пор пока не станет почти O(1). Примерно так и с GC. EP>>Штуки типа cuckoo hashing не на ровном месте появились. dot>Не понял, оно worst case (не путаем с amortised) не меняет же вроде, так же O(n).
Меняет — поиск и удаление константы в худшем случае.
EP>>Для hashtable есть альтернативы с гарантированной сублинейной сложностью, и там где гарантия нужна — их и используют. Причём можно комбинировать — снаружи hashtable, а внутри узлов при превышении лимита что-то логарифмическое — тогда будет суб-линейная гарантия. dot>Так и gc не лыком шиты.
И что? Это меняет их сложность?
dot>>>>>Так храни так же и в Java, т.е. приведённый выше array, не вижу проблему. EP>>>>Проблема в том для каждого типа элемента нужен будет отдельный Java код. dot>>>Не смертельно. EP>>Отдельный код для каждой комбинации. Конечно не смертельно, можно и на ASM'е писать рабочий код. dot>Комбинации чего?
Структура данных * контейнер * алгоритм * etc. ЕМНИП даже в C# для разных структур generic даёт разные воплощения.
dot>Сколько их? (только практику плз, а не теоретические рассуждения)
Очень много, это практика, реальный код.
Например вызвал сортировку для вектора со своим замыканием-предикатом — получил отдельный код оптимизированный конкретно под эту комбинацию.
dot>Если можно было бы — писали бы и на асме, в LL все средства идут в ход.
Вряд ли получится ASM лучше того что даст C++, за какое-нибудь разумное время. Интринсинки — да, полезны, но это не ASM.
dot>>>>>Если ты про ссылочное дерево — то уже всё плохо, ибо оно не будет в памяти последовательно. EP>>>>Деревья используются на практике. Хранение данных в самом узле позволяет избавится от лишней индерекции. dot>>>Это какие-то очень экзотические условия, у меня не получается представить когда в ссылочном дереве лишняя индирекция может стать серьёзной проблемой. EP>>А например в хэш-таблице? dot>Если значение большое, то индирекция нужна, иначе сам массив хеш-таблицы будет слишком большим и не помещаться в кеш.
1. Если малое — то уж точно не нужна, тут разногласия нет.
2. В описываемой тобой схеме получается: сначала latency на cache hit (пусть и небольшая) для того чтобы достать ссылку, потом latency на cache miss/поход в RAM, плюс кэш забивается лишними указателями, что снижает эффективность. Если же убрать индерекцию — то получается сразу поход в RAM, который есть и твоей схеме
3. Ключ может хранится отдельно от значения, причём без индерекции.
dot>Если значение маленькое, то это скорее всего будет примитив.
С чего бы это?
EP>>>>>>Так тут есть простой выбор — by-value или by-reference. Это совершенно не тоже самое что и засучив рукава нарезать байт-буфера на структуры dot>>>>>by-value — и тут ВНЕЗАПНО появляется O(N) от числа живых объектов. EP>>>>Далеко не всегда. Да и почему внезапно-то? dot>>>Настолько же ВНЕЗАПНО как и в случае с GC. EP>>Ок, допустим, в случае чего by-value заменим, не проблема — пара закорючек. dot>И поимеем битые указатели.
Слушай, я уже не в одном сообщении признавал, что в этом смысле у GC реальный и очевидный плюс. Я же не говорю что битые указатели невозможны, что есть гарантия (хотя при желании и её можно получить).
К чему ты опять повторяешься?
EP>>В случае с GC что будешь делать? dot>Подстрою GC.
Подстройка называется GC-free/off-heap , да?
dot>>>>>by-reference — и тут начинаются проблемы с временем жизни, засучив рукава начинаешь решать проблемы владения. EP>>>>В 99.999% случаях ничего "засучивать" не нужно, и никакие *_ptr не нужны. dot>>>Так в этих же случаях и в яве всё будет всё в YG, а значит никакого жуткого O(N). EP>>Нет же, случаи принципиально разные. Где-то наверху callstack делаем: EP>>
...
EP>>
ничего не "засучивая". EP>>Этот массив, по терминам GC, спокойно может попасть под классификацию OG dot>Сам массив это ровно одна ссылка.
И в элементах тоже ссылки.
dot>Элементы — пусть лежат, если ты не создаёшь|удаляешь их постоянно, а просто меняешь их поля — GC вообще не парится. GC ведёт себя плохо если постоянно меняется граф объектов долго лежащих в памяти.
Если короче, то вот это утверждение неверное:
dot>Так в этих же случаях и в яве всё будет всё в YG, а значит никакого жуткого O(N).
dot>Собственно это соответствует сложному жонглированию владением в C++,
Не сложному, и не соответствует. Большинство случаев владения (и "жонглирования" им) C++ это простейший by-value.
dot>где это запросто приведёт к битым указателям, если у вас в команде не Александреску с Страуструпом под руководством Кнута.
"Запросто" не приведёт. А вот valgrind запросто отловит.
dot>>>>>Это мы переходим в другую плоскость — выразительность языка, а не собственно JVM/GC. Для JVM есть и другие языки — Scala, Ceylon, Kotlin и прочее, которые позволяют и многие твои любимые абстракции. EP>>>>А мы ВНЕЗАПНО не JVM обсуждаем, а вполне конкретную Java. Если брать JVM — то например если в неё скомпилировать C++ — то он там положит всех на лопатки dot>>>Не положит, к сожалению. Иначе бы уже давно компилировали. dot>>>Вся эта указательная магия и арифметика, юнионы, и прочий low level не может быть покрыт GC и JVM ссылками, поэтому при компиляции С/C++ память будет внутри byte[]. EP>>Конечно будет, и это одна из причин почему положит на лопатки. EP>>Именно так и происходит
в Emscripten, который компилирует C++ в JS. EP>>И JS кстати получается реально быстрый. На одном из тестов работает практически в два раза быстрее чем аналогичный код на C#. JS, в веб-браузере, Карл! И этом при том что в C# версии были структуры. Если же брать аналогичный код на Java — то всё будет ещё круче Можем кстати сравнить. dot>Ну и кому эти микробенчмарки нужны?
Тем кого интересует скорость
dot>Ты давай пример системы на плюсах, компилированных под jvm.
Я не знаю нормального компилятора C++ -> JVM. Есть даже мысли за-proof-of-concept'ить такой.
dot>Это же полная лажа.
Что конкретно "лажа"?
dot>Как дойдёт до времени отклика или тупо многопоточности (как там многопоточность в JS, кстати?), то всё и станет на свои места.
Причём тут многопоточность JS? Какое время отклика? Ты о чём? Я мысли читать не умею.
dot>Кстати, это, конечно, очень субъективно, но когда я искал работу (London), я всегда писал Java/C++ и выбирал finance. И из ~сотни интерьвю не было ни одного С++. Выводы, конечно, можно сделать разные... но всё же.
Конечно субъективно — мне как раз оттуда приходили варианты C++, правда не finance, и я вообще не искал. И что характерно не было ни одной Java.
EP>>>>Нормальные IDE есть. Да автоматический анализ кода сложнее, но сложнее не из-за выразительности, а из-за внутренних особенностей сложившихся исторически. Языку больше тридцати лет, а если брать с базу C (из которой многие недостатки и произрастают) — то больше сорока. EP>>>>При этом аналогичную выразительность можно достичь не делая проблемы анализаторам. dot>>>Может и можно... Я сходу не могу сделать такое заявление. EP>>>>Те же структуры есть в C#. dot>>>А толку-то от них... EP>>Не нужно вручную нарезать массивы на структуры dot>И что это даёт? Что позволяет добиться?
Добиться меньшего количества низкоуровневого error-prone кода.
Здравствуйте, Serginio1, Вы писали:
_>>Аааа, так оно ещё и через COM это делается... ) Тогда уж точно никакой разницы с другими языками нет, причём уже прямо сейчас. Т.е. банально реализуем соответствующий COM интерфейс и без проблем используем его в 1C. Не знаю правда зачем, но делается это тривиально. ))) S> Тебе нужно делать обертку Idispatch над объектом, типом. В Net это делается через Reflection к любому типу, объекту S>Раз это элементарно забацайка. В той статье класс оборачивает любой объект, тип. Поддержка энумераторов. S>Давай прямо сейчас. S> Это еще раз подтверждение того, что ты невнимательно читаешь ссылки
S>Что было понятно то основной метод такой обертки для вызова свойства метода реального объекта.
Вот конкретный пример, правда там обвёртка к Python, а не IDispatch, но тем не менее:
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
// ...
}
// указываем те методы которые хотим экспортировать:
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
// можно сократить до вот такого варианта:
PYTHON_CLASS_SIMPLIFIED
(
hello,
World,
greet, set
)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
_>>>Аааа, так оно ещё и через COM это делается... ) Тогда уж точно никакой разницы с другими языками нет, причём уже прямо сейчас. Т.е. банально реализуем соответствующий COM интерфейс и без проблем используем его в 1C. Не знаю правда зачем, но делается это тривиально. ))) S>> Тебе нужно делать обертку Idispatch над объектом, типом. В Net это делается через Reflection к любому типу, объекту S>>Раз это элементарно забацайка. В той статье класс оборачивает любой объект, тип. Поддержка энумераторов. S>>Давай прямо сейчас. S>> Это еще раз подтверждение того, что ты невнимательно читаешь ссылки
S>>Что было понятно то основной метод такой обертки для вызова свойства метода реального объекта.
EP>Вот конкретный пример, правда там обвёртка к Python, а не IDispatch, но тем не менее: EP>
EP>// наш класс:
EP>struct World
EP>{
EP> void set(std::string msg) { this->msg = msg; }
EP> std::string greet() { return msg; }
EP> std::string msg;
EP>};
EP>// указываем те методы которых хотим экспортировать:
EP>BOOST_PYTHON_MODULE(hello)
EP>{
EP> class_<World>("World")
EP> .def("greet", &World::greet)
EP> .def("set", &World::set)
EP> ;
EP>}
EP>// можно сократить до вот такого варианта:
EP>PYTHON_MODULE_SIMPLIFIED
EP>(
EP> hello,
EP> World,
EP> greet, set
EP>)
EP>
EP>Помимо этого есть автоматические генераторы клея между языками типа SWIG — там даже методы перечислять не нужно.
Ну вы совсем, что ли не читаете? Автоматически любой тип, объект. Или для всех возможных классов будете клей городить?
И как правило свойства класса это не простые типы, а другие классы. Методы тоже принимают параметры в виде объектов. Вызов статических методов класса итд.
Удосужтесь хоть прочитать код. Там совсем другая песня.
Еще раз любой класс или объект оборачивается вокруг
public class AutoWrap : IReflect
{
// Два основных поля Объект и его типprotected internal object O = null;
protected internal Type T = null;
Конструкторы
public AutoWrap(object obj)
{
O = obj;
if (O is Type)
{
T = O as Type;
ЭтоТип = true;
}
else
{
T = O.GetType();
ЭтоТип = false;
}
}
// Бывает нужно обратиться не к статическим методам, а к методат типаpublic AutoWrap(object obj, Type type)
{
O = obj;
T = type;
ЭтоТип = false;
}
public object ТипКакОбъект(object Тип)
{
if (Тип is AutoWrap)
Тип = ((AutoWrap)Тип).T;
Type T = ((Type)Тип);
return new AutoWrap(T, T.GetType());
}
Здравствуйте, Serginio1, Вы писали:
EP>>Помимо этого есть автоматические генераторы клея между языками типа SWIG — там даже методы перечислять не нужно. S> Ну вы совсем, что ли не читаете? Автоматически любой тип, объект. Или для всех возможных классов будете клей городить?
SWIG автоматически делает для любого типа, без ручного перечисления (хотя можно и вручную перечислить — там это опционально).
S>И как правило свойства класса это не простые типы, а другие классы.
Тоже не проблема — главное указать что для какого класса экспортируется.
S>Методы тоже принимают параметры в виде объектов.
Не проблема, список параметров с их типами автоматически выводится. В примере не указанны параметры у метода set, причём там параметр это std::string.
S>Вызов статических методов класса итд.
Там в одном из примеров показывается даже как внешнюю функцию добавить в класс как метод
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
EP>>>Помимо этого есть автоматические генераторы клея между языками типа SWIG — там даже методы перечислять не нужно. S>> Ну вы совсем, что ли не читаете? Автоматически любой тип, объект. Или для всех возможных классов будете клей городить?
EP>SWIG автоматически делает для любого типа, без ручного перечисления (хотя можно и вручную перечислить — там это опционально).
S>>И как правило свойства класса это не простые типы, а другие классы.
EP>Тоже не проблема — главное указать что для какого класса экспортируется.
Угу так надо все возможные классы указывать.
S>>Методы тоже принимают параметры в виде объектов.
EP>Не проблема, список параметров с их типами автоматически выводится. В примере не указанны параметры у метода set, причём там параметр это std::string.
S>>Вызов статических методов класса итд.
EP>Там в одном из примеров показывается даже как внешнюю функцию добавить в класс как метод
Еще раз. Я не знаю, вообще какие классы буду использовать. Твои обертки статические, а мои во время исполнения. Разница есть?
За подсчетом ссылок кстати следит прокси Net. А как там у вас?
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
EP>>>>Помимо этого есть автоматические генераторы клея между языками типа SWIG — там даже методы перечислять не нужно. S>>> Ну вы совсем, что ли не читаете? Автоматически любой тип, объект. Или для всех возможных классов будете клей городить? EP>>SWIG автоматически делает для любого типа, без ручного перечисления (хотя можно и вручную перечислить — там это опционально). S>>>И как правило свойства класса это не простые типы, а другие классы. EP>>Тоже не проблема — главное указать что для какого класса экспортируется. S> Угу так надо все возможные классы указывать.
Это полуавтоматический вариант. Если нужен автоматический — бери например SWIG
S>>>Вызов статических методов класса итд. EP>>Там в одном из примеров показывается даже как внешнюю функцию добавить в класс как метод S> Еще раз. Я не знаю, вообще какие классы буду использовать. Твои обертки статические, а мои во время исполнения. Разница есть?
Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии
S>За подсчетом ссылок кстати следит прокси Net. А как там у вас?
EP>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии
Я беру любую нетовскую сборку и использую её. Есть свои сборки. То есть любую без предварительного описания.
Могу сгенерить на лету. Кроме того, сборки имеют свойство меняться.
Нету у вас рефлекшина.
S>>За подсчетом ссылок кстати следит прокси Net. А как там у вас?
EP>Wrapper вестимо, а в чём проблема?
Наверное проблема в зоопарке менеджеров памяти.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Evgeny.Panasyuk, Вы писали:
S>> Еще раз. Я не знаю, вообще какие классы буду использовать. Твои обертки статические, а мои во время исполнения. Разница есть?
EP>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии
The primary limitation of IDispatch is that it assumes that objects are static. In other words, since objects do not change during run time, type information can fully describe them at compile time.
Так что то, что у него там что-то "в runtime" — это, скорее недостаток, чем достоинство.
Если не поможет, будем действовать током... 600 Вольт (C)
Здравствуйте, Serginio1, Вы писали:
EP>>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии S> Я беру любую нетовскую сборку и использую её.
От native варианта ты что хочешь? Взять любую DLL и сделать к ней wrapper?
S>Есть свои сборки. То есть любую без предварительного описания.
Ещё раз, SWIG не требует предварительного описания.
S>Нету у вас рефлекшина.
Нету, это недостаток, сейчас кое-как эмулируется. При этом reflection не обязательно должен быть runtime — он может быть compile-time, и такой скорей всего и введут.
S>>>За подсчетом ссылок кстати следит прокси Net. А как там у вас? EP>>Wrapper вестимо, а в чём проблема? S> Особенно на стеке
Ты о чём?
S>В Net value тип боксится
В C++ объект любого типа можно создать где угодно (не считая несколько экстремальных случаев к теме не относящихся) — в любой кучке байт достаточного размера
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
EP>>>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии S>> Я беру любую нетовскую сборку и использую её.
EP>От native варианта ты что хочешь? Взять любую DLL и сделать к ней wrapper?
Мой врапер работает с любой DLL без предварительного описания. В рефлекшине все есть.
S>>Есть свои сборки. То есть любую без предварительного описания.
EP>Ещё раз, SWIG не требует предварительного описания.
А что делает SWIG? Ты должен получить врапер причем статически. Или он компилирует на лету по исходникам?
То есть я могу обратиться к любой C++ DLL и SWIG на лету по информации о типе сгенерирует врапер?
Ну вот, а говорите, что рефлекшина нет. S>>Нету у вас рефлекшина.
EP>Нету, это недостаток, сейчас кое-как эмулируется. При этом reflection не обязательно должен быть runtime — он может быть compile-time, и такой скорей всего и введут.
А зачем рефлекшн в compile-time? Он нужен как раз в runtime.
S>>>>За подсчетом ссылок кстати следит прокси Net. А как там у вас? EP>>>Wrapper вестимо, а в чём проблема? S>> Особенно на стеке
EP>Ты о чём?
S>>В Net value тип боксится
EP>В C++ объект любого типа можно создать где угодно (не считая несколько экстремальных случаев к теме не относящихся) — в любой кучке байт достаточного
размера
Кстати в примерах только value типы. Нет там примеров с объектами, типами итд.
Как ваш описатель врапера разберется с зоопарком менеджеров памяти?
Кстати единственный вариант , это когда есть подсчет ссылок. Я так понимаю, что у вас там куча вариантов даже по этой теме
Возьмем пример. Например у тебя есть структура с кучей полей объектов этакое дерево с циклическими ссылками
И тебе эту структуру нужно передать на сторону клиента. Врапер структуру обернул. Но у структуры то нет подсчета ссылок?
и солнце б утром не вставало, когда бы не было меня
S> public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
S> { // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)
S> if (name == "[DISPID=-4]")
S> {
S> return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
S> }
[поскипана куча]
S>
Дай угадаю, "[DISPID=-4]" — это С-шный
#define DISPID_NEWENUM ( -4 )
Это ты придумал со строкой сравнивать, или это работа мастера?
Но, вообще, это не код, это... короче, C# — ассемблер современности.
Ты уверен, что как ты написал — так это и должно делаться?
На Visual C++ ты напишешь типа того:
[
object,
dual // Это разрешает поддержку IDispatch
]
interface MyInterface
{
// твои методы
};
[
coclass,
default(MyInterface)
]
class MyClass
{
// реализации методов
};
А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).
И если ты всё руками делаешь — tlb откуда возьмётся?
Если не поможет, будем действовать током... 600 Вольт (C)
Здравствуйте, Serginio1, Вы писали:
EP>>>>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии S>>> Я беру любую нетовскую сборку и использую её. EP>>От native варианта ты что хочешь? Взять любую DLL и сделать к ней wrapper? S> Мой врапер работает с любой DLL без предварительного описания. В рефлекшине все есть.
Нет, не с любой
S>>>Есть свои сборки. То есть любую без предварительного описания. EP>>Ещё раз, SWIG не требует предварительного описания. S> А что делает SWIG? Ты должен получить врапер причем статически. Или он компилирует на лету по исходникам?
Он делает весь glue code по исходникам.
S>>>Нету у вас рефлекшина. EP>>Нету, это недостаток, сейчас кое-как эмулируется. При этом reflection не обязательно должен быть runtime — он может быть compile-time, и такой скорей всего и введут. S> А зачем рефлекшн в compile-time? Он нужен как раз в runtime.
Нет, нам-то как раз нужен в compile-time. Из compile-time reflection нетрудно перейти в runtime, а вот обратно уже нет.
По факту же большинство случаев использования refleciton прекрасно укладываются в compile-time.
S>>>В Net value тип боксится EP>>В C++ объект любого типа можно создать где угодно (не считая несколько экстремальных случаев к теме не относящихся) — в любой кучке байт достаточного размера S>Кстати в примерах только value типы. Нет там примеров с объектами, типами итд. S>Как ваш описатель врапера разберется с зоопарком менеджеров памяти?
Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, Serginio1, Вы писали:
S>>
S>> public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
S>> { // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)
S>> if (name == "[DISPID=-4]")
S>> {
S>> return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
S>> }
MX> [поскипана куча]
S>>
MX>Дай угадаю, "[DISPID=-4]" — это С-шный MX>
MX>#define DISPID_NEWENUM ( -4 )
MX>
Это запрос комовского Энумератора. MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames
MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.
MX>Ты уверен, что как ты написал — так это и должно делаться?
Это используется уже кучу лет.
MX>На Visual C++ ты напишешь типа того:
MX>
MX>[
MX> object,
MX> dual // Это разрешает поддержку IDispatch
MX>]
MX>interface MyInterface
MX>{
MX> // твои методы
MX>};
MX>[
MX> coclass,
MX> default(MyInterface)
MX>]
MX>class MyClass
MX>{
MX> // реализации методов
MX>};
MX>
MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).
MX>И если ты всё руками делаешь — tlb откуда возьмётся?
А зачем tlb? Есть ITypeInfo котрый и реализуется во врапере методы IReflect. Да и Idispatch и он не нужен. 1С прекрасно без него обходится
Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
// [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]public interface IEventFor1C
{
[DispId(0x60020000)]
void Событие();
[DispId(0x60020001)]
void СобытиеСПараметром(object value);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
[ComSourceInterfaces(typeof(IEventFor1C))]
public class ClassForEvent1C
{
[ComVisible(false)]
public delegate void Событие_Delgate();
public delegate void СобытиеСПараметром_Delgate(object value);
public object Объект;
private SynchronizationContext Sc;
public ClassForEvent1C(object Объект,String СобытиеОбъекта,bool ЕстьПараметр=false)
{
this.Объект = Объект;
BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);
if (!ЕстьПараметр)
ei.AddEventHandler(Объект, new System.Action(ВнешнееСобытие));
else
ei.AddEventHandler(Объект, new System.Action<object>(ВнешнееСобытиеСПараметром));
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
Sc = SynchronizationContext.Current;
}
public event Событие_Delgate Событие;
public event СобытиеСПараметром_Delgate СобытиеСПараметром;
private void ВнешнееСобытие()
{
if (this.Событие != null) //Событие();
Sc.Send(d => Событие(), null);
}
private void ВнешнееСобытиеСПараметром(object value)
{
if (this.СобытиеСПараметром != null) //Событие();
Sc.Send(d => СобытиеСПараметром(AutoWrap.ОбернутьОбъект(value)), null);
}
}
Либо пишу ручками используя анонимные типы. И подписка
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
EP>>>>>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии S>>>> Я беру любую нетовскую сборку и использую её. EP>>>От native варианта ты что хочешь? Взять любую DLL и сделать к ней wrapper? S>> Мой врапер работает с любой DLL без предварительного описания. В рефлекшине все есть.
EP>Нет, не с любой
Докажи. S>>>>Есть свои сборки. То есть любую без предварительного описания. EP>>>Ещё раз, SWIG не требует предварительного описания. S>> А что делает SWIG? Ты должен получить врапер причем статически. Или он компилирует на лету по исходникам?
EP>Он делает весь glue code по исходникам.
Ну вот, а говоришь, что не требует предварительного описания. S>>>>Нету у вас рефлекшина. EP>>>Нету, это недостаток, сейчас кое-как эмулируется. При этом reflection не обязательно должен быть runtime — он может быть compile-time, и такой скорей всего и введут. S>> А зачем рефлекшн в compile-time? Он нужен как раз в runtime.
EP>Нет, нам-то как раз нужен в compile-time. Из compile-time reflection нетрудно перейти в runtime, а вот обратно уже нет. EP>По факту же большинство случаев использования refleciton прекрасно укладываются в compile-time.
У нас все в реал тайме. Можно подкинуть любую сборку и работать либо по утинной типизации, либо по информации о типе
S>>>>В Net value тип боксится EP>>>В C++ объект любого типа можно создать где угодно (не считая несколько экстремальных случаев к теме не относящихся) — в любой кучке байт достаточного размера S>>Кстати в примерах только value типы. Нет там примеров с объектами, типами итд. S>>Как ваш описатель врапера разберется с зоопарком менеджеров памяти?
EP>Каким зоопарком? Ты о чём?
То есть у вас как в Delphi один менеждер памяти? Все классы поддерживают подсчет ссылок?
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
EP>>>>>>Причём тут "во время исполнения"? Ты свой класс, для которого нужен IDispatch, меняешь в runtime? Ты этого не говорил в условии S>>>>> Я беру любую нетовскую сборку и использую её. EP>>>>От native варианта ты что хочешь? Взять любую DLL и сделать к ней wrapper? S>>> Мой врапер работает с любой DLL без предварительного описания. В рефлекшине все есть. EP>>Нет, не с любой S>Докажи.
Возьми любую native dll
S>>>>>Есть свои сборки. То есть любую без предварительного описания. EP>>>>Ещё раз, SWIG не требует предварительного описания. S>>> А что делает SWIG? Ты должен получить врапер причем статически. Или он компилирует на лету по исходникам? EP>>Он делает весь glue code по исходникам. S> Ну вот, а говоришь, что не требует предварительного описания.
Это исходный класс что-ли предварительное описание?
S>>>>>В Net value тип боксится EP>>>>В C++ объект любого типа можно создать где угодно (не считая несколько экстремальных случаев к теме не относящихся) — в любой кучке байт достаточного размера S>>>Кстати в примерах только value типы. Нет там примеров с объектами, типами итд. S>>>Как ваш описатель врапера разберется с зоопарком менеджеров памяти? EP>>Каким зоопарком? Ты о чём? S> То есть у вас как в Delphi один менеждер памяти?
Не один, и здесь в этом нет проблемы. COM объекты создаются и удаляются на одной стороне.
S>Все классы поддерживают подсчет ссылок?
Это всё прекрасно реализуется неинтрузивно.
Нет подсчёта ссылок: