Форум: "Начинающим";
Текущий архив: 2009.12.13;
Скачать: [xml.tar.bz2];
Вниз<B>DLL</B> не грузится, если в ней <B>TChart</B> Найти похожие ветки
← →
vlad2 (2009-10-21 14:12) [0]Если в DLL помещаю объект типа TChart, то библиотека перестаёт грузиться, при этом GetLastError даёт 0 ("Операция успешно завершена").
Как создать TChart в DLL?
Спасибо.
← →
Медвежонок Пятачок © (2009-10-21 14:18) [1]при этом GetLastError даёт 0
Значит все успешно грузится.
← →
Сергей М. © (2009-10-21 14:25) [2]
> Как создать TChart в DLL?
Точно так же как не в DLL
← →
vlad2 (2009-10-21 14:28) [3]Хэндл = 0 :(
← →
Сергей М. © (2009-10-21 14:29) [4]Какой хэндл-то ?
← →
Dennis I. Komarov © (2009-10-21 14:38) [5]
> Какой хэндл-то ?
Извесно какой, Desktop ;)
← →
vlad2 (2009-10-21 14:47) [6]...
hLib: HModule;
...
hLib:=LoadLibrary(...);
вот hLib нулевой, т.е. длл не загрузилась.
← →
Dennis I. Komarov © (2009-10-21 14:51) [7]
> Извесно какой, Desktop ;)
"т" забыл....
← →
Сергей М. © (2009-10-21 14:56) [8]
> вот hLib нулевой, т.е. длл не загрузилась
Тогда утверждение
> при этом GetLastError даёт 0
ложно.
← →
vlad2 (2009-10-21 17:01) [9]> Тогда утверждение
> при этом GetLastError даёт 0
> ложно.
В этом и парадокс, что и хэндл = 0 и GetLastError = 0.
← →
Сергей М. © (2009-10-21 17:07) [10]Так-с ..
Докладай, что ты видишь в рез-те выполнения этогоhLib:=LoadLibrary(...);
Win32Check(hLib > 0);
кода ?
← →
Медвежонок Пятачок © (2009-10-21 17:08) [11]В этом и парадокс, что и хэндл = 0 и GetLastError = 0.
LoadLibrary("неправильная длл");
GetUserName(....)
GetLastError
← →
vlad2 (2009-10-21 17:47) [12]> Сергей М. ©
> Докладай, что ты видишь в рез-те выполнения этого
>
> hLib:=LoadLibrary(...);
> Win32Check(hLib > 0);
>
>кода ?
Вижу "Stack overflow" :(
← →
vlad2 (2009-10-21 17:54) [13]Медвежонок Пятачок ©
> LoadLibrary("неправильная длл");
> GetUserName(....)
> GetLastError
имя правильное, GetLastError = 0
← →
Сергей М. © (2009-10-21 18:58) [14]Так у тебя ж лажа в самой DLL)
← →
Сергей М. © (2009-10-21 19:13) [15]
> vlad2 (21.10.09 17:54) [13]
По барабану правильное оно или неправильное.
LoadLibrary у тебя вернула ноль, установив при этом LastError<>0
GetUserName нишиша не вернула, но безусловно установила при этом LastError=0, благополучно похерив при этом причины ошибки, возникшей при предыдущем LoadLibrary
Следующая GetLastError, разумеется, вернула ноль.
Подозрение на то, что у тебя этот случай, т.е. ты тем или иным макаром собственноручно поганишь LastError в ноль и потом удивляешься почему так получается)
← →
vlad2 (2009-10-21 19:46) [16]Всем спасибо за участие.
Путём самозабвэнных поисков и шаманских заклинаний добился эксепшена "A class named TChartAxisTitle already exists" при загрузке длл. А на эту ошибку народ уже нарывался. Правда, в других случаях (обновление тичарта), но их манипуляции навели на простую мысль подлинковать пакаджи TChart"а не только в длл, но и в главном приложении (где они и даром не были нужны). Это нехитрое действие позволило убрать ошибку.
← →
Германн © (2009-10-21 19:50) [17]
> навели на простую мысль подлинковать пакаджи TChart"а не
> только в длл, но и в главном приложении (где они и даром
> не были нужны).
Значит теперь это так называется? Подлинковать :)
← →
Сергей М. © (2009-10-21 19:58) [18]
> vlad2 (21.10.09 19:46) [16]
А расскажи-ка нам, шаман, про свои прыжки с бубном вокруг крыжиков "Build With Run-Time Packages" в обоих проектах ..
Тогда, пожалуй, станет ясно, где что нужно или не нужно, даром или не даром ..
← →
Amoeba © (2009-10-22 00:04) [19]
> vlad2 (21.10.09 19:46) [16]
Кажись приходим к пониманию, какие грабли подстерегают тех, кто пытается запихать объекты VCL в динамические (DLL) библиотеки.
← →
Германн © (2009-10-22 00:42) [20]
> Кажись приходим к пониманию, какие грабли подстерегают
> тех, кто пытается запихать объекты VCL в динамические (DLL)
> библиотеки.
>
Не. Пока что пеняем на "кривость" TChart"а. :)
← →
vlad2 (2009-10-22 14:28) [21]> Сергей М. © (21.10.09 19:58) [18]
Если в секции "Build With Run-Time Packages" проекта главного приложения не стоят библиотеки tee..., то длл с ТChart"ом не грузится.
В проекте длл эти же пакаджи тоже стоят.
Наверное, всё-таки "кривость" TChart"а.
> Германн © (21.10.09 19:50) [17]
> Значит теперь это так называется? Подлинковать :)
Извиняйте, тёмен, батюшка :).
← →
Сергей М. © (2009-10-22 15:40) [22]
> vlad2 (22.10.09 14:28) [21]
А что, твоя DLL экспортирует функции или процедуры, в которых данные типа TChart фигурируют в параметрах или результатах ?
← →
Германн © (2009-10-22 16:36) [23]
> vlad2 (22.10.09 14:28) [21]
>
> > Сергей М. © (21.10.09 19:58) [18]
>
> Если в секции "Build With Run-Time Packages" проекта главного
> приложения не стоят библиотеки tee..., то длл с ТChart"ом
> не грузится.
> В проекте длл эти же пакаджи тоже стоят.
> Наверное, всё-таки "кривость" TChart"а.
>
Да, да. Кривее не бывает. :)
← →
Сергей М. © (2009-10-22 16:43) [24]
> Если в секции "Build With Run-Time Packages" проекта главного
> приложения не стоят библиотеки tee
Зато там у тебя наверняка наверняка фигурируют vcl и rtl - этого достаточно чтобы получить граблями при любой степени кривости или прямости тичарта.
← →
vlad2 (2009-10-22 17:50) [25]> Сергей М. ©
> А что, твоя DLL экспортирует функции или процедуры, в которых данные типа TChart фигурируют в параметрах или результатах ?
В результатах. Экспортируемая функция строит график и бросает его в файл.
> Зато там у тебя наверняка наверняка фигурируют vcl и rtl
Фигурируют.
> этого достаточно чтобы получить граблями при любой степени кривости или прямости тичарта
Не понял. Раньше проблем с загрузкой длл не было.
← →
Сергей М. © (2009-10-22 20:18) [26]
> В результата
Т.е. DLL экспортирует некую ф-цию с прототипом
function SomeExportedFunc(..): TChart;
?
← →
vlad2 (2009-10-22 23:02) [27]
> Сергей М. © (22.10.09 20:18) [26]
>
> Т.е. DLL экспортирует некую ф-цию с прототипом
>
> function SomeExportedFunc(..): TChart;
Объект TChart определён, создан и используется только внутри функции. "Импортёр" функции не обязан знать, как там строится график. Таким образом, если не знаешь про TChart, то пользоваться этой длл нельзя :(.
← →
Германн © (2009-10-23 00:43) [28]
> Объект TChart определён, создан и используется только внутри
> функции.
> Экспортируемая функция строит график и бросает его в файл.
Интересно что за "график", для построения которого необходимо непременно использовать VCL-компонент TChart? Или всё дело в "бросает его в файл"?
← →
Сергей М. © (2009-10-23 08:20) [29]Хрень какая-то ..
Как это так ?
С одной стороны
> Импортёр" функции не обязан знать, как там строится график
и при этом
> если не знаешь про TChart, то пользоваться этой длл нельзя
??
← →
Сергей М. © (2009-10-23 08:47) [30]
> Импортёр" функции не обязан знать, как там строится график
Вполне логично.
Тогда зачем вuses
хост-проекта или каких-то из юнитов в его составе у тебя фигурирует юнит TeEngine ?
← →
vlad2 (2009-10-23 11:40) [31]Получается так, что всё работает, только если в проект и длл, и гл.приложения включён пакадж tee. Если из проекта гл.приложения исключить tee, то длл не грузится, что является, по-моему, показателем кривизны тичарта. Потому что какой бы кривой длл ни была, она грузится в любом другом приложении, если я не использую тичарт и НЕ грузится, если использую тичарт, а в приложениях не загружен tee.
← →
Сергей М. © (2009-10-23 11:54) [32]
> она грузится в любом другом приложении, если я не использую
> тичарт
Вот и не используй тичарт нигде - ни в списке линкуемых bpl, ни в спискахuses
.
← →
vlad2 (2009-10-23 12:12) [33]
> Сергей М. © (23.10.09 11:54) [32]
>
> Вот и не используй тичарт нигде
Т.е. предлагаешь строить графики ручками?
← →
Игорь Шевченко © (2009-10-23 12:31) [34]Если я правильно понимаю ситуацию, то:
1. Имеется некая DLL, которая наружу экспортирует функцию построения графика (и неважно, каким компонентом он будет построен)
2. Если DLL использует TeeChart, то DLL не загружается
3. Если DLL скомпилирована с пакетами и приложение скомпилировано с пакетами, то для успешной загрузки необходимо, чтобы приложение тоже ссылалось на TeeChart
Я не ошибся ?
← →
vlad2 (2009-10-23 12:35) [35]
> Игорь Шевченко © (23.10.09 12:31) [34]
> Если я правильно понимаю ситуацию, то:
> 1. Имеется некая DLL, которая наружу экспортирует функцию
> построения графика (и неважно, каким компонентом он будет
> построен)
> 2. Если DLL использует TeeChart, то DLL не загружается
> 3. Если DLL скомпилирована с пакетами и приложение скомпилировано
> с пакетами, то для успешной загрузки необходимо, чтобы приложение
> тоже ссылалось на TeeChart
>
Да.
← →
Сергей М. © (2009-10-23 12:37) [36]
> vlad2 (23.10.09 12:12) [33]
> предлагаешь строить графики ручками?
Я предлагаю выкорчевать из проекта хост-приложения все упоминания о тичарте, а не только из списка используемых пакетов времени выполнения.
Это полностью соответствует как твоим требованиям
> "Импортёр" функции не обязан знать, как там строится график
в частности, так и здравому смыслу использования плагинов в целом.
← →
vlad2 (2009-10-23 13:02) [37]
> Сергей М. © (23.10.09 12:37) [36]
>
> Я предлагаю выкорчевать из проекта хост-приложения все упоминания
> о тичарте
Не помогает :(
← →
Игорь Шевченко © (2009-10-23 13:02) [38]vlad2 (23.10.09 12:35) [35]
Пытаюсь воспроизвести ситуацию:
Есть проект:unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{$WARN SYMBOL_PLATFORM OFF}
procedure TForm1.Button1Click(Sender: TObject);
type
TPlotChartProc = procedure (AParent: TWinControl);
var
LibHandle: HMODULE;
PlotChartProc: TPlotChartProc;
begin
LibHandle := LoadLibrary("ChartDLL.DLL");
Win32Check(LibHandle > 0);
@PlotChartProc := GetprocAddress(LibHandle, "PlotChart");
Assert(Assigned(PlotChartProc));
PlotChartProc(Self);
end;
end.
Есть DLLlibrary ChartDll;
uses
SysUtils,
Classes,
ChartDllMain in "ChartDllMain.pas";
{$R *.res}
exports
PlotChart;
begin
end.
И юнит в этой DLLunit ChartDllMain;
interface
uses
Controls;
procedure PlotChart (AParent: TWinControl);
implementation
uses
TeeProcs, TeEngine, Chart;
procedure PlotChart (AParent: TWinControl);
var
Chart1: TChart;
begin
Chart1 := TChart.Create(AParent);
with Chart1 do
begin
Name := "Chart1";
Parent := AParent;
Left := 92;
Top := 32;
Width := 400;
Height := 250;
Title.Text.Clear;
Title.Text.Add("TChart");
TabOrder := 1;
end;
end;
end.
Никаких ошибок в проекте не возникает, DLL загружается, Chart показывается.
Проект на пакет от TeeChart не ссылается никаким образом
← →
Сергей М. © (2009-10-23 13:10) [39]
> Не помогает
Не верю.
Показывай все uses в хост-проекте и его юнитах ..
← →
vlad2 (2009-10-23 14:27) [40]
> Сергей М. © (23.10.09 13:10) [39]
>
> Не верю.
И правильно :).
Когда создал голое приложение без тичарта, длл нормально загрузилась. Тогда стал внимательно смотреть свой проект (он довольно большой и закрученный) и нашёл-таки маленький старый паршивый юнит со ссылкой на тичарт, который в данном приложении, конечно, не нужен. Это была последняя ссылка, после удаления которой всё пошло.
Большое спасибо Сергею М. и Игорю Шевченко, чьи посты подвигли меня на более жёсткий досмотр проекта.
← →
Сергей М. © (2009-10-23 14:32) [41]
> vlad2 (23.10.09 14:27) [40]
Ну победить-то ты победил, с чем тебя и поздравляем, а вот где была засада и кто в ней сидел - ты, видимо, так и не понял)
← →
vlad2 (2009-10-23 14:36) [42]
> Сергей М. © (23.10.09 14:32) [41]
>
> где была засада и кто в ней сидел
?
← →
Сергей М. © (2009-10-23 14:50) [43]
> vlad2 (23.10.09 14:36) [42]
И хост-приложение и DLL при включенных крыжиках использования ран-тайм пакетов пользуют один и тот же экз-р RTL, который ведет списки зарегистрированных классов.
Стартует хост-приложение и при инициализации юнита тичарт-движка (ибо он фигуририрует в uses) регистрирует в RTL соотв.классы, в т.ч. TChartAxisTitle.
Далее хост-приложение грузит либу, в которой в uses также фигурирует тичарт-движок, который для инициализации получает управление, при этом лезет в ту же RTL для регистрации тех же классов, которые там ранее были зарегистрированы хост-приложением, и получает при этом отлуп в виде исключения "A class named ... already exists", ибо в одном и том же списке зарегистрированных классов НЕ может быть двух одноименных классов.
← →
vlad2 (2009-10-23 16:16) [44]
> Сергей М. © (23.10.09 14:50) [43]
А почему же этого не происходит, если в хост-приложение мы включаем tee?
← →
Leonid Troyanovsky © (2009-10-23 16:20) [45]
> vlad2 (23.10.09 16:16) [44]
> А почему же этого не происходит, если в хост-приложение
> мы включаем tee?
Видимо, в борьбе под ковром побеждает хост.
--
Regards, LVT.
← →
Сергей М. © (2009-10-23 16:27) [46]
> vlad2 (23.10.09 16:16) [44]
Хост-приложение при инициализации грузит пакет tee, тот в свою очередь при своей инициализации регистрирует в RTL свои классы.
Теперь ты грузишь свою либу. Система же при загрузке либы видит, что tee уже имеется в АП процесса и не грузит ее, соотв-но повторная иниц-ция tee не происходит.
← →
vlad2 (2009-10-23 16:38) [47]
> Сергей М. © (23.10.09 16:27) [46]
Большое спасибо, Сергей. Теперь понятно.
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.12.13;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.011 c