http://www.gamedev.ru/download/?id=7449
Всё качается :)
Ты наверно не туда кликаешь.
Не считаю что со стороны автодоски есть какая-либо дискриминация кого-либо, просто они могли бы сделать интерфейс через COM, а-ля DX, но это же требует много человеко-часов. А то что есть сейчас - отлично работает.
Собственно, не сложно сделать оболочку, что я и продемонмтрировал. Развивать тему имеет смысл в плане поднятия версии до 9тки :) У меня всё никак не находится времени на это. А для восьмерки всё вполне можно использовать, геометрия, текстуры, скининг, материалы, user info в пропертях объекта.
Я именно об этом. Соотв. код у них явно писался еще до появления COM\DCOM, не говоря уж обо всяких там дотнет. Статическая подлинковка либов сегодня - каменный век. Ориентировка на конкретный язык в эпоху глобализации и интеграции - тоже :-)
PS. Файл скачал с работы. Дома почему-то не отображается кнопка "скачать". Буду разбираться. Вы мыло свое не подсветите? Если вдруг вопросы возникнут, проконсультируете?
Проконсультирую конечно, ты прям здесь спрашивай, надо же базу знаний накапливать ;)
Например, я не очень понимаю, как они в DLL классы загоняют. В свое время основательно штудировал MSDN по этому вопросу, но ничего не нашел. Только функции. Я заблуждаюсь?
Так же как на дельфях - достаточно знать структуру класса. SDK для макса - это и есть описание структуры классов. Это готовый фреймворк, набор .h файлов. Подключаешь нужные, пишешь свой код - вот тебе и dll-плагин. Я не силён в сях, там вроде .lib файлы для линковки библиотек в рантайме.
А при чем тут .h-файлы? DLL не умеет хранить поля классов. Она не знает, что такое класс. Она хранит функции. Если маразм не изменяет, перечень их можно посмотреть утилитой dumpbin.
Есть класс
class Foo: public Bar {
public:
BOOL A;
BOOL funcA(int B);
Foo();
~Foo();
}
Что будет в DLL? DumpBin что покажет?
Аналогично на делфях:
Foo = class(Bar)
public
A: Boolean;
constructor Create(B: integer);
end;
Его в DLL как засунуть? Я знаю только один способ - в виде отдельных функций. При этом, все наследование пойдет прахом и с полями придется что-то решать. Я не прав?
Ты не ту тему для этого вопроса выбрал ;)
Вообще CPP имена функций класса как-то хитро переименовывает, добавляя кучу всякой инфы и спец симвлов.
Странно, по-моему, это как раз та самая тема. Наилучшим вариантом при написании плагина на делфи я считаю сокарщение (а лучше полный отказ) от сишного кода. Для этого надо заставить МАХ проглотить DLL написанную на делфи. Вот я и думаю, как это сделать. Хотя бы для простейшего случая...
А, ну да, идея хороша. Только мне кажется по сложности реализации это будет жесть. Я в эту сторону сначала подумал и сразу бросил, ибо си я не знаю, а уж структуру его либ и подавно.
Еще минус в жесткой привязки к версии компиллера (в восьмом максе до сих пор юзается .net студия, не помню какая она там по версии). Это вообще всё сугубо системно. Вот если бы борланд в своё время не отошел от объектной модели obj файлов а-ля c, то мы бы ща на дельфи даже дрова уровня ядра писать могли бы (впрочем, на тройке можно, в четверке уже нет).
Я не разбираюсь ни разу в тонкостях .lib файлов (да и в "толкостях" тоже ;) ) поэтому пошел по пути наименьшего сопротивления.
Суть плагина - вернуть ссылку на класс. А потом уже сам 3D msx этот класс юзает и так и эдак. Т.е. это не просто тупой вызов функций, это полноценный класс - таблица функций (совсем не простая), ну и прочая cpp байда. У дельфи своя байда, у cpp своя. И они очень разные, эти байды :) Эмулировать сёвый класс на дельфе - это утопия имхо.
Хм... Си не знаешь, а 2/3 своего SDK на нем написал? OBJ-файлы тут не причем. Я занимался промышленной автоматизацией и работал с людьми, которые спокойно писали драйверы устройств и код нулевого кольца на делфях. В подробности не вдавался. Ограничился изучением Рихтера, Соломона и Руссиновича. Так вот нигде я не видел упоминания, что DLL может экспортировать классы. Если найдешь, покажи. Вот что в SDK`Help пишут:
"Core Interfaces
3ds Max provides a large number of functions for plugins to use. There are two approaches plugins may use to call these functions in 3ds Max:
Plugins can directly call functions in CORE.DLL
They may call methods on an interface pointer.
...
..."
Ключевое слово - FUNCTIONS !
LIBы тоже не при делах. MAX кушает не либы, а DLL. А DLL это чисто системная штука, она как раз и задумана для языковой независимости программ. Внутреннее представление классов DEPLHI и MSVC - это другой разговор. Но ведь COM\DCOM как-то работает? Серверная часть может быть на делфях, а клиентская на сях и наоборот. Это те же классы, только заголовки в реестре регистрируются. Короче, сейчас поизучаю докуменитацию и начну сам эксперименты ставить. Авось чего и нарисуется. Интересно, DUMPBIN.EXE можно где-нибудь отдельно от MSVC скачать?
>Хм... Си не знаешь, а 2/3 своего SDK на нем написал?
Ну, на это знаний хватило. :) Плюс яндекс с гуглем.
>MAX кушает не либы, а DLL. А DLL это чисто системная штука, она как раз и задумана для языковой независимости программ.
Ну, зачем dll нужна я знаю ;) А вот Max хватает именно класс. Указатель на экземпляр класса.
Вот DllEntry.cpp - в нем описаны экспортируемые функции.
// This function returns the number of plug-in classes this DLL __declspec( dllexport ) ClassDesc* LibClassDesc(int i) { switch(i) { case 0: return GetDelphiPluginDesc(); default: return 0; } }
Т.е. по номеру плугина мы должны вернуть указатель на созданный объект, что мы и делаем:
модуль DelphiPlugin.cpp
static DelphiPluginClassDesc DelphiPluginDesc; ClassDesc2* GetDelphiPluginDesc() { return &DelphiPluginDesc; }
Просто макс знает структуру класса, так же как и плагин знает (последний благодаря описанию в файлах SDK). Всё сводится к простой передачи указателя на объект. Так что роль функций в dll здесь минимальна.
Ну а на счет цитаты из Help'а - тут видимо говориться о том, что часть функционала обернуто в классы, а часть можно вызывать напрямую, как обычные функции - например, GetMasterScaleHide, GetFrameRate, GetTicksPerFrame. Так что тут нет ключевого слова имхо :)
Эээ, возвращать указатель на класс и экспортировать класс - разные вещи. Указатель это просто 32-битное(вроде) число. А уж как его трактовать - другое дело. Интерфейсы COM на разных языках написанные работают? Это ведь те же классы. Порылся сегодня в РСДН и нашел такую ветку:
http://www.rsdn.ru/Forum/?mid=1647072
Надо экспериментировать. Боевой плагин может и не получится, а Hello world на делфи было бы прикольно :-)))
>Эээ, возвращать указатель на класс и экспортировать класс - разные вещи.
согласен.
Я же написал - тут как раз максу возвращается ссылка на готовый экземпляр класса. Не на класс, а на объект.
Coriolis прав. Экспорт Си++ классов из ДЛЛ-ки ничто иное как просто экспорт методов, которым передается указатель на этот класс.
Просто эти методы знают как прикастить этот указатель (this).
Так же само и вызывающая сторона, знает какой именно указатель нужно передать в функцию-в-дллке - передать указатель this.
Почему в МСДНне не написано -- потому что это чисто Си++ хак, и ничего более. Все равно в ДЛЛ экспортируются ТОЛЬКО функции(методы). На дельфе тже такое можно замутить.
А хак потому что классы в ДЛЛ и в вызывающей программе должны совпадать НА БИНАРНОМ УРОВНЕ (чтоб можно было корректно прикастить). Одна сторона скомпилена другим компилятором - большая вероятность что работать не будет.
Про СОМ.
Для него есть СПЕЦИФИКАЦИЯ описывающая его ФОРМАТ ПРЕДСТАВЛЕНИЯ КЛАССА В ПАМЯТИ (на бинарном уровне)
И компилятор уже не в праве менять это представление - он уже должен следовать стандарту. Потому и СОМ всегда является СОМом, и никаких проблем с совместимостью у него нет (ну почти)
Ну, во-первых, никто и не спорит, что оно возвращает именно указатель на класс. Я просто на всякий случай еще раз заострил внимание, что экспорт класса - сомнительная вещь.
Про COM и формат представления. Я возможно уже забыл за давностью лет, но по-моему, в C++ интерфес COM это ничто иное, как асбстрактный базовый класс, где все методы виртуальные. В делфях было специальное ключевое слово interface, но ИМХО, оно там больше для красоты. По-моему, экземпляры класса в машкоде одинаково представляются (с учетом объявления методов cdecl ), но пока спорить не готов, на неделе поэкспериментирую, тогда и будет ясность.
Тема в архиве.