Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.046 c
4-1155818349
Term
2006-08-17 16:39
2006.12.24
Compact Framework Preview Compiler


15-1164898770
olevacho_
2006-11-30 17:59
2006.12.24
Защита приложения о копирования


15-1164991793
ReWD
2006-12-01 19:49
2006.12.24
Коммивояжер - минимальное оставное дерево


15-1164923196
Германн
2006-12-01 00:46
2006.12.24
Программа для тестирования CD/DVD приводов


4-1155739454
webpauk
2006-08-16 18:44
2006.12.24
Проверка строковой переменной





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский