[builder] вопрос к отцам.

Slavaga

Ситуация:
Есть форма: TForm *Form1 в проекте Porject1.
Есть проект Project2, который компилиться в DLL.
В этой DLL есть функция
extern "C" void CALLBACK __export SomeFunction1(TForm * Source, TComponent * AOwner)
{
TButton * Button1;
Button1 = new TButton(AOwner);
Button1->Caption = "Some button";
Source->InsertControl(Button1); //(*)
}
После компиляции получается DLL-файл.
Эта функция вызывается из первого проекта.
На строке (*) вылетает эксцепшн примерно следующего содержания:
Project project1.exe raised exception class EConvertError with message 'Cannot assign a TFont to a TFont'. Bla-bla-bla.
Что бы это могло значить и как с этим бороться?
Изначально предполагалось, что после передачи функции значений (TForm*)Form1 и (TComponent*)AOwner она добавляет на форму кнопку.

vijrel7878

у dll и приложения разные менеджеры памяти, поэтому создавать что-то в dll-ке и затем втыкать в объекты приложения нельзя

Slavaga

А разве DLL не подгружается в адрессное пространство главного модуля?

vijrel7878

да, подгружается в адресное пространство приложения. Но не для этого.
Менеджер памяти для каждой dll-ки свой и следить за своей памятью должна именно дллка, а приложение за своей.

Slavaga

И все-таки непонятно, почему получается ошибка. Работаю-то я с абсолютными адресами объектов. Может ты знаешь, как работает метод InsertControl? Или знаешь, где это можно посмотреть. Версия билдера - 6.

vijrel7878

метод InsertControl вставляет то, что ты передаешь в коллекцию Controls формы. По идее, так как у тебя реализовано, падать должно при закрытиии приложения.
Проверь еще чтобы ф-ции работала по одинаковому соглашению, как правило это stdcall.
Для начала поставь stdcall, а потом избавься от конструирования кнопки в библиотеке. Либо позаботься о том, чтобы эта кнопка убивалаять перед закрытием формы в dll, при этом удаляляясь из коллекции controls формы (только не деструктором!).
Хотя на мой взгляд - это извращение, гораздо проще организовать создание кнопки в приложении, передавая из dll-ки лишь необходимые параметры.

vijrel7878

Почему еще может падать:
VCL (а Tform - класс VCL) написана на паскале. Если в заголовочном файле ф-ции идут в другом порядке, чем реализованы в VCL, работать ничего не будет. Т.е. вообще говоря, вызывать методы объекта на самом деле уместно только лишь тогда, когда ты сам написал это на одном языке и точно можешь гарантировать последовательность методов.

Slavaga

Проблема как раз не в том, что глюк появляется при закрытии приложения, а наоборот. Ошибка возникает при вызове метода InsertControl.
А насчет создания кнопки в приложении я думал. Просто хочу написать приложение, которое можно было бы легко расширять при помощи таких dll'ов. Сказал ему имя dll'а и имя функции,которую первой вызвать и которая добавит в главную форму все необходимые элементы - и все. Можно конечно на апи попробовать, но тогда нету смысла писать на билдере, а я уже как-то привык к тупому написанию обработчиков. Эх! Че-ж делать-то?

vijrel7878

про инсерт контрол последний пост - то что падает, очень похоже что вызывается метод не по нунжному адресу, что делать - пост перед этим

Slavaga

А такая ситуация:
Есть метод и есть апи. Имеют одинаковое название. В частности SetParent.
В первом случае:
virtual void __fastcall SetParent(TWidgetControl* AParent);
Во втром,
HWND SetParent(HWND ChildWindow, HWND NewParent);
Как объяснить компилятору, что надо запускать апи, а не метод?

vijrel7878

нужно явно его специфицировать.
В твоем случае будет Windows.SetParent(...) (если объявление в windows.h)
хе, а вообще это дело автоматом должно рюхнуться, поскольку по параметрам ф-ции разные.
То что я написал вначале применимо если и названия одинаковые и список параметров...

Slavaga

Будь проклят VCL,MFC и все высокоуровневое программирование!
Да здравстует Assembler и WinAPI !

Slavaga

Еще вопрос. Можно ли из приложения запустить новое самостоятельное окно (такое, на которе Alt-Tab'ом можно переключиться)?
Оставить комментарий
Имя или ник:
Комментарий: