Здравствуйте!
Сдаюсь на вашу милость дамы и господа, поскольку сломал уже всю голову, а обсуждения имеющиеся на подобные проблемы в форуме не привели к результату.
Итак, имеется Form1 с Label1 и код в этой форме динамически вызывает custom.dll ищет функцию showlabel(TForm *)
код этой функции в dll следующий
на форме в результате ничего нет, так как видимо debuglabelmc->Parent=NULL
но если добавляю следующую строчку после создания TLabel
debuglabelmc->Parent=(TWinControl*)F->Handle;
то получаю Access violation at address 00E043C6 in module "custom.dll". Read of address 00150612
Что я делаю не так? как надо правильно?
Есть условие, приложение и dll должны быть собраны без rtp, библиотека должна подключаться динамически и в нее передаваться указатель или хэндл главной формы.
_>то получаю Access violation at address 00E043C6 in module "custom.dll". Read of address 00150612
_>Что я делаю не так? как надо правильно?
ну, всё-таки (TWinControl*)F->Handle это виндовый хэндл, а никак не наследник TControl, вам так не кажется? если я правильно понимаю, debuglabelmc->Parent должен быть объектом, наследником TControl.
_>Есть условие, приложение и dll должны быть собраны без rtp, библиотека должна подключаться динамически и в нее передаваться указатель или хэндл главной формы.
точно ли указатель на хэндл главной формы, а не указатель на объект главной формы?
Здравствуйте, pdn_mail, Вы писали:
_>Здравствуйте! _>Сдаюсь на вашу милость дамы и господа, поскольку сломал уже всю голову, а обсуждения имеющиеся на подобные проблемы в форуме не привели к результату. _>Итак, имеется Form1 с Label1 и код в этой форме динамически вызывает custom.dll ищет функцию showlabel(TForm *)
При работе с DLL следует забыть про классы Builder: (TForm *) в DLL и (TForm *) в EXE абсолютно разные классы, потому как у них свои RTTI. Исключение составляет только особый вид DLL — BPL. Поэтому использовать только типы Windows, что-то наподобие:
Ну эти ответы к сожалению из области теории, потому-что:
showlabel(TForm *MainForm) //здесь я передаю указатель на объект главной формы, причем указывается тип класса формы VCL, а не мой определенный TForm1, просто так надо и к последствиям не приводит.
{
TForm1 *F=(TForm1*)MainForm; // здесь я присваиваю новому указателю тип своей главной формы, инспектор в дебагере четко показывает что F это точно указатель на объект моей формы и соответственно F->Handle это ее хэндл.
...
}
такой код
g_debuglabelmc->ParentWindow = hwndParent;
вызывает ошибку компиляции [C++ Error] Unit1.cpp(222): E2316 'ParentWindow' is not a member of 'TLabel'
проходит только такой вариант
debuglabelmc->Parent->ParentWindow=F->Handle;
но опять получаю Access violation at address 00DD6653 in module "custom.dll". Read of address 00000030
Почему? да потому-что debuglabelmc->Parent = NULL следовательно присваивание значения ParentWindow приводит к этой ошибке.
debuglabelmc->Parent=F->Handle;
вызывает ошибку компиляции [C++ Error] Unit1.cpp(223): E2034 Cannot convert 'void *' to 'TWinControl *' потому и преобразовываю к (TWinControl *)
У кого еще есть какие мысли как побороть эту ситуацию?
Здравствуйте, pdn_mail, Вы писали:
_>Ну эти ответы к сожалению из области теории, потому-что: _>showlabel(TForm *MainForm) //здесь я передаю указатель на объект главной формы, причем указывается тип класса формы VCL, а не мой определенный TForm1, просто так надо и к последствиям не приводит.
К сожалению, это еще и практика...
А то, что не работает разве не есть последствия?
_>
_>{
_>TForm1 *F=(TForm1*)MainForm; // здесь я присваиваю новому указателю тип своей главной формы, инспектор в дебагере четко показывает что F это точно указатель на объект моей формы и соответственно F->Handle это ее хэндл.
_>...
_>}
_>
Привидение типа в C-стиле — очень грубый маневр, таким образом, можно привести к любому типу любой указатель на память
_>такой код _>
_>g_debuglabelmc->ParentWindow = hwndParent;
_>
_>вызывает ошибку компиляции [C++ Error] Unit1.cpp(222): E2316 'ParentWindow' is not a member of 'TLabel' _>проходит только такой вариант _>
Увы, я забыл, что TGraphicControl -> TCustomLabel ->TLabel, и соответственно не имеет ParentWindow
_>У кого еще есть какие мысли как побороть эту ситуацию?
то debuglabelmc->Parent=F; вызывает ошибку Project application.exe raised exception class EConvertError with message 'Cannot assing a TFont to a TFont'. Process stoped. Use Step or Run to continue.
Причем любым другим свойствам объекта дает присваивать значения и вызываются методы нормально.
Да блин, опять косяк какой-то. а теперь то что надо? почему он не дает присвоить значение свойства Parent созданного в dll объекта? только из-за того что Owner у него при создании была главная форма приложения?
Что интересно в таком варианте все работает из dll, хоть и вылетает на присваивании Parent, но debuglabelmc на форме появляется
Получается что для Label присваивать значение Parent не надо и последующие строки тоже не обязательны. Достаточно для отображения на форме следующего кода в dll ?
_>Получается что для Label присваивать значение Parent не надо и последующие строки тоже не обязательны. Достаточно для отображения на форме следующего кода в dll ? _>
Здравствуйте, pdn_mail, Вы писали:
_>вот такие пироги
Учите матчасть
Во-первых, динамическая память в dll и exe управляется разными менеджерами памяти, если только не используется общий менеджер памяти как того рекомендует dll-wizard в комментарии. Без общего менеджера при передаче динамических структур (классов, строк и т.п.) между dll и exe ошибки AV неизбежны.
Во-вторых, одноименные классы в dll и в exe — это не одно и тоже, если только как уже было сказано вместо dll не используется bpl.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true