Поддержка тоталовских плагинов в своих программах
Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер
Задумал я использовать WDX плагины в одном из своих. Но не знаю, как решить одну проблему. По WDX спецификации после загрузки должна быть вызвана функция ContentSetDefaultParams, а перед выгрузкой ContentPluginUnloading. Поскольку WDX плагин может быть загружен как TC, так и моим плагином одновременно, то эти функции могут быть вызваны дважды. Мы не знаем, какой код помещает разработчик в эти функции, и поскольку у TC и моего плагина одно адресное пространство, то это может привести к повторной инициализации и преждевременной финализации данных, что в конечном счете IMHO может привести к сбоям в работе TC или плагина. Единственное, что я придумал, это копировать перед началом работы с WDX плагином этот плагин и остальное содержимое папки, в которой он лежит, в temp`овую директорию и работать с ним. Как другие решают эту проблему, или это не проблема вовсе?
Рекомендую обрабатывать DLLEntryPoint для идентификации загрузчика:
Добавленно:
Сорри, задумался и недопонял суть вопроса. То что выше для самописного плага с поддержкой такой возможности.
ВDLL_PROCESS_ATTACH идентифицируем подключение тоталом,
в DLL_THREAD_ATTACH подключение плагином.
А для твоей ситуации - прожка лоадер+pipes.
Код: Выделить всё
procedure DLLEntryPoint(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: ShowMessage('Attaching to process');
DLL_PROCESS_DETACH: ShowMessage('Detaching from process');
DLL_THREAD_ATTACH: MessageBeep(0);
DLL_THREAD_DETACH: MessageBeep(0);
end;
end;
begin
{ First, assign the procedure to the DLLProc variable }
DllProc := @DLLEntryPoint;
{ Now invoke the procedure to reflect that the DLL is attaching to the
process }
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.Сорри, задумался и недопонял суть вопроса. То что выше для самописного плага с поддержкой такой возможности.
ВDLL_PROCESS_ATTACH идентифицируем подключение тоталом,
в DLL_THREAD_ATTACH подключение плагином.
А для твоей ситуации - прожка лоадер+pipes.
Reason = DLL_THREAD_ATTACH обозначает только то, что в процессе создан еще один поток. Мой плагин может загружать и вызывать функции из WDX плагина и в основном потоке, так что это ничего не меняет.в DLL_THREAD_ATTACH подключение плагином.
Самому грузить плагин, минуя LoadLibrary? Ну спасибо, я лучше буду через temp директорию работать.А для твоей ситуации - прожка лоадер+pipes
Сколько плагинов, столько и проблем. То, что в одном плагине сработает, то в другом может привести к access violation. Меня интересует общее универсальное решение.Ты проведи тесты на каком нить плагине, тогда и узнаешь точно.
Это означает только то - что библиотеку вызвали потоком.Reason = DLL_THREAD_ATTACH обозначает только то, что в процессе создан еще один поток.
И списки айди этих потоков, процессов можно классифицировать, разделить и понять кто вызывал данный плагин.Мой плагин может загружать и вызывать функции из WDX плагина и в основном потоке, так что это ничего не меняет.
Но тебе это не поможет, у тебя другая засада. Это решение для поддержки твоего вопроса из плагина.
Насчёт лоадера, ты меня недопонял: пишешь небольшую прожку-прослойку между твоим плагином и вызываемым плагином.Самому грузить плагин, минуя LoadLibrary? Ну спасибо, я лучше буду через temp директорию работать
Коннектишься с этой прожкой через трубы (или через что угодно, хоть сокеты используй) и управляешь через неё вызванным плагином(передаёшь ей параметры вызовов, она передаёт плагу и обратно).
Адрессные пространства у тотала и твоей прожки разные - соответственно не будет описанных тобой проблем. А access violation этого плагин-лоадера не затронут тотал...
Если я правильно понял, ты хочешь работать с WDX плагинами, так же, как SuperWdx, InfoPacker, WDXGuide и т.д.Dec писал(а):Как другие решают эту проблему, или это не проблема вовсе?
В практическом плане никто из них, пока, ни на какую проблему (связанную с многократной загрузкой!) не наткнулся.
В теории, может возникнуть плагин, который будет делать с этим проблемы, но это вряд ли.
ЗЫ.
Нет. Dec прав, DLL_THREAD_ATTACH обозначает, что в процессе создан еще один поток. В MSDN четко написаноB4rr4cuda писал(а):Это означает только то - что библиотеку вызвали потоком.
DLL_THREAD_ATTACH Indicates that the current process is creating a new thread.
В общем виде ответ очевиден - когда dll использует данные, специфические для потока.B4rr4cuda писал(а):Интересно, надо подумать как это можно использовать....
Например, многие объекты MFC не могут передавться из потока в поток. И если dll обменивается такими объектами с вызывающим модулем, то они должны быть созданы свои для каждого потока.
Другой пример - допустим есть сервер, который для обслуживания запросов создает потоки. Часть обработки вынесена в dll, который может быть вызван из любого потока. В этом случае иногда в TLS потока (thread local storage) хранят и сам запрос и все, что нужно для его обслуживания.
В любом случае - экзотика.
Да ради бога, я же не против. Я бы в данном случае не стал париться, но это потому, что я неграмотный программист.Грамотный программист, к коим я приписываю себя (возможно ошибочно), обязан предусмотреть такую ситуацию.
Но очень мне хотелось бы знать как ты собираешься предусмотреть и другую ситуацию.
Большинство моих знакомых программистов, которые пишут dll, независимо от их уровня грамотности, заглядывают в MSDN, где умные (а может и глупые, бог их разберет) дядьки из MS говорят:Dec писал(а):Единственное, что я придумал, это копировать перед началом работы с WDX плагином этот плагин и остальное содержимое папки, в которой он лежит, в temp`овую директорию и работать с ним.
А это означает, что DllMain с параметром DLL_PROCESS_ATTACH вызывается только один раз для каждого процесса, а значит тут-то, как правило, и делают инициализацию всех данных, специфических для процесса (если таковые есть, конечно) пребывая в уверенности, что это происходит только один раз в процессе. Но эти дядьки не знают, что может прийти грамотный программист и скопировать dll в другую директорию, создав, тем самым, ситуацию, когда будет две попытки загрузить один и тот же dll из разных мест. Хотя ему, конечно, известно, что такое Dll Hell и, стопроцентно, он знает, что при этом DllMain с DLL_PROCESS_ATTACH будет вызван повторно для того же dll в том же процессе.Even if an application calls LoadLibrary() for a DLL more than once, the DLL entry point, DllMain(), is called only once and only one DLL_PROCESS_ATTACH entry is created.
Я уже и не спрашиваю, что ты будешь копировать, если в директории плагина вдруг окажется NTFS линк на чертову прорву мегабайт.