Форум: "KOL";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];
ВнизВопрос по классам KOL... Найти похожие ветки
← →
rainstuff (2006-03-13 02:18) [0]У меня вот такой вопрос, возможно ламерский:)
Насколько я понял, PCanvas:=^TCanvas;
Тогда почему не работает код:
var
canv1:PCanvas;
canv2:TCanvas;
begin
canv1:=Form.Canvas;
canv2:=canv1^;
canv2.TextOut(10,10,"123");
end;
Delphi 5, Kol 2.33, Windows XP
Спасибо.
← →
ECM © (2006-03-13 09:55) [1]Потому, что canv2 (как область памяти) оказывается неинициализированной.
Самое главное в ней отсутствует ссылка на VMT, вернее она указывает на произвольную область памяти и при копировании объекта, функция System._ObjCopy не может правильно определить размер объекта (возможно даже прочитать ячейку где хранится размер) - дальше AV.
Для объекта обязательно должна быть вызвана функция Setup._ObjSetup
компилятор сам добавит её вызов при вызове конструктора
← →
ECM © (2006-03-13 12:57) [2]
> Setup._ObjSetup
Опечатка System._ObjSetup
← →
rainstuff (2006-03-13 15:48) [3]Спасибо, за ответ, но я не совсем понял, как вызвать эту функцию....
А можно пример, если не сложно?
← →
ECM © (2006-03-13 16:41) [4]
> но я не совсем понял, как вызвать эту функцию....
Очень просто
1) _ObjSetup:
New(canv1,Create());
2)_ObjCopy
canv2 := canv1^;
Компилятор сам вставит вызовы за вас :))
Либо нужно писать на ассемблере.
А вообще-то я не вижу никакого смысла в использовании статических или автоматических объектных переменных (не-указателей). Компилятор не вызывает для них автоматически конструктор-деструктор, выделение-освобождение памяти, как например для строк. Для классов это уже заложено изначально - только ссылки. Поэтому совет - пользуйтесь только указателями на объектный тип и не заморачивайтесь.
Хотя можно и извратится, например так:
PInteger(@canv2)^ := Integer(TypeOf(TCanvas));
canv2 := Form.Canvas^;
canv2.TextOut(10,10,"123");
← →
rainstuff (2006-03-13 16:50) [5]Спасибо!
Да я б не заморачивался, но дело в том, что у меня есть dll, написанная на Delphi с использованием VCL. И туда в функцию надо передать объект для последующей обработки. К примеру, в dll есть такая функция:
function PluginExec(Canvas:TCanvas):Boolean;
Если писать без KOL - передаётся туда PlugExec(Canvas) и всё работает...
А вот когда стал писать на KOL, то возникли некоторые проблемы...
← →
ECM © (2006-03-13 17:02) [6]Вот именно!
function PluginExec(Canvas: TCanvas):Boolean; (VCL TCanvas - class)
Canvas - ссылка (грубо говоря указатель) 4 байта
соответствует в KOL следующему:
function PluginExec(Canvas: PCanvas): Boolean;
т.е. передается в ДЛЛ указатель на объект основной программы - как и вслучае VCL. Если же писать TCanvas в KOL - будет передаваться копия переменной через стэк
:)
← →
rainstuff (2006-03-13 17:27) [7]Я пробовал... вызывал PluginExec(Form.Canvas),но почему-то вылетает с RuntimeError...
потому и подумал, что может дело в указателях...
← →
ECM © (2006-03-13 17:57) [8]Ну... тут может быть тысяча причин..:)) Надо увидеть как в DLL используется этот указатель. А вообще-то (ИМХО) пользоваться в DLL объектами (классами) основной программы не есть хорошо. Где гарантия, что в основной программе и в DLL используется одна и таже версия - вплоть до двоичного представления (теоритически возможна разница допустим при одной и той же версии исходного кода но при разных опциях компилятора) и тогда жди AV...Немного легче при использовании стандартных компонент VCL(они не обновляются часто, по крайней мере в пределах одной версии Delphi) - но и там я бы не стал так делать. Если надо что-то нарисовать из DLL в контекст основной программы - передайте DC
(Canvas.Handle)
← →
rainstuff (2006-03-13 18:03) [9]хм... может так и сделаю...
а вылетает оно как раз после попытки что-нибудь нарисовать, если конкретно:
Canvas.TextOut(X,50,"123");
← →
rainstuff (2006-03-13 18:41) [10]Не, с дескриптором тоже не получается - в программе работает, а в dll - нет... (специально написал свою dll...)
без KOL всё работает на ура... где собака зарыта я так и не понял...
Ладно, бум копать:)
В любом случае - спасибо за помощь:)
← →
rainstuff (2006-03-13 19:06) [11]С DC настроил - всё работает, но при передаче Canvas по-прежнему вылетает...
← →
Vladimir Kladov (2006-03-13 20:53) [12]В DLL и в экзешнике различные менеджеры памяти. Т.е. они может и одинаковые даже, если версии совпадают, но память выделяется в разных областях памяти и структурах кучи. А теперь представьте себе... Представили? И больше никогда не пассируйте объекты между DLL и экзешником. Даже если вдруг заработает. Сохраните себе кучу нервных окончаний.
← →
Vladimir Kladov (2006-03-13 21:12) [13]Думал, добавить, не добавить. Ну ладно, рискну. Если из головной программы в DLL передать адрес структуры MemoryManager, и в DLL в этом вызове (первом) вызвать SetMemoryManager, то это будет полный аналог uses sharemem в VCL Delphi. т.е. куча становится общая, и проблемы исчезнут. Но все равно, лучше так не делать. KOL не VCL, версии меняются часто. Поля в объектах "плавают", и при несовпадении версии случиться может что угодно, вплоть до синего экрана или форматирования винта (без шуток). Лучше объекты и Huge (Ansi) string не пассировать никогда и ни под каким соусом.
← →
ECM © (2006-03-13 21:24) [14]Полностью поддерживаю... думал про то же ... донести правильно не сумел. :(
:))
← →
rainstuff (2006-03-13 23:56) [15]Мне просто интересно стало- почему не работает:)
Про разные области памяти я знал, но не знал, что это может привести к таким сурьёзным последствиям...
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.04 c