Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.28;
Скачать: CL | DM;

Вниз

Так, а если общение через интерфейс, но интерфейс в DLL?   Найти похожие ветки 

 
Mx ©   (2005-08-05 12:20) [0]

Нужен ли тогда ShareMem? Допустим загружаем DLL, а она экспортирует функцию для создания объекта, с которым потом общаемся через интерфейс (объект не COM, но интерфейс реализует, как IDesigner в Delphi). Будут ли проблемы со string"ами (не бельем, естественно)?


 
Digitman ©   (2005-08-05 12:47) [1]

смысл, необходимость и логика использования Sharemem в случае взаимодействия с dll через интерфейсы ничем не отличаются от случая "обычного" взаимодействия


 
Mx ©   (2005-08-05 13:03) [2]


> Digitman ©   (05.08.05 12:47) [1]

Торможу, так нужен ShareMem или нет? Если можно, по-подробнее.


 
wal ©   (2005-08-05 13:08) [3]

Если через интерфейс будешь строки (string) или дин. массивы передавать, то нужен, если нет, то не нужен, А почему бы сразу на COM не замахнуться, а не только на интерфейсы?

С уважением.


 
Alexander Panov ©   (2005-08-05 13:09) [4]

Mx ©   (05.08.05 13:03) [2]
для интерфейсов правила, которые описаны в Wizard-dll - те же самые.


 
Mx ©   (2005-08-05 13:11) [5]

Ну вот, расстроили меня... :(


 
DiamondShark ©   (2005-08-05 13:16) [6]

А в чём расстройство-то?
Если интерфейсы используются только как фича языка, то действуют все те же правила, что и для любых других конструкций.


 
Digitman ©   (2005-08-05 13:39) [7]


> Mx ©   (05.08.05 13:03) [2]


используешь ты интерфейсы или не используешь - без разницы, правила использования ShareMem едины и касаются динам.типов данных, передаваемых как параметры dll-вызовов и получаемых как результаты этих вызовов

разницы нет никакой -  то ли ты вызвал из ДЛЛ непосредственно ф-цию SomeFunction(), то ли ты вызвал некий метод некоего интерфейса SomeInterface.SomeMethod()

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

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

Sharemem необходим в случаях , когда взаимодействующие модули (передающие между собой, например, данные дин.типов) разрабатываются в среде Делфи/BCB и при сборке этих модулей использованы разные зн-я опции Build With Run-Time Packages

Sharemem не требует своего использования, если все взаимодействующие модули были собраны с опцией Build With Run-Time Packages = True, при этом они будут использовать единый менеджер памяти, который находится в ран-тайм-библиотеке, загружаемой в АП процесса единожды и используемой впоследствии всеми модулями.


 
Mx ©   (2005-08-05 14:22) [8]


> Digitman ©   (05.08.05 13:39) [7]
> разные экз-ры менеджеров памяти

Вот оказывается в чем проблема? Гм... тогда сделаю пакеты, тем более потом еще и в Kilyx"е будут использовать.


 
GLFox ©   (2005-08-05 15:16) [9]

А лучше всего использовать PChar, чтобы не тащить ShareMem с собой.


 
Mx ©   (2005-08-05 15:37) [10]

Есть консольное приложение:

program CnConsole;

{$APPTYPE CONSOLE}

type
 TConsoleClient = class(TInterfacedObject, IClientInterface)
 end;

function CreateAppObject: IApplicationInterface; external "SomeLib.dll";

var
 Client: IClientInterface;
 App: IApplicationInterface;
begin
 App := CreateAppObject;
 try
   Client := TConsoleClient.Create;
   App.Connect(...);
 except
   on E: Exception do
     WriteLn(...);
 end;
 WriteLn("Press ENTER to continue...");
 ReadLn;
end.


В этой самой SomeLib.dll имеем класс:

type
 TConceptApplication = class(TInterfacedObject, IApplicationInterface)
 private
 ...
 end;

var
 ConceptApplication: TConceptApplication;

implementation

...

end.


и экспортируемая фукнция:

function CreateAppObject: IConceptApplication;
begin
 Result := TConceptApplication.Create;
end;


Так вот, созданный объект App не разрушается, а вроде как счетчик ссылок при выходе должен был сам на нуль свалить. Почему так?


 
Mx ©   (2005-08-05 15:39) [11]

Ну почему нельзя редактировать своё сообщения? Порой такие несуразные ошибки!

С типами я в примере напутал. Результат у CreateAppObject естественно IApplicationInterface.


 
GLFox ©   (2005-08-05 15:46) [12]

А непосредственно сделать так:
App := nil
не пробовал?


 
Alexander Panov ©   (2005-08-05 15:50) [13]

Mx ©   (05.08.05 15:37) [10]
Так вот, созданный объект App не разрушается,


А в какой момент он должен быть у тебя разрушен?


 
Mx ©   (2005-08-05 15:50) [14]


> GLFox ©   (05.08.05 15:46) [12]

Так пробовал - работает. Но почему автоматом этого не происходит? В GUI такого не было. Неужели в чем-то различие? Или я что-то упустил?


 
Mx ©   (2005-08-05 15:54) [15]


> Alexander Panov ©   (05.08.05 15:50) [13]
> А в какой момент он должен быть у тебя разрушен?

Я так понимаю, когда приложение закрывается. Ну, например, как с дин. массивами. Еще раз пересмотрел свой старый GUI проект, там такой объект (правда не из DLL сконструированный) записывается в поле формы в ее конструкторе. Разрушается он самостоятельно, никаких nil ему не присваивается.


 
GLFox ©   (2005-08-05 16:01) [16]

>Mx ©   (05.08.05 15:54) [15]

>> Alexander Panov ©   (05.08.05 15:50) [13]
>> А в какой момент он должен быть у тебя разрушен?

>Я так понимаю, когда приложение закрывается.

Когда приложение закрывается винда и так уничтожит все связанные с ним ресурсы.
А вообще, рекомендую почитать книгу Эрика Хармона "Разработка COM-приложений в среде Delphi". Книга хоть и не новая, но про интерфесы там весьма доходчиво написано.


 
Digitman ©   (2005-08-05 16:04) [17]


> Mx ©   (05.08.05 15:50) [14]


ты его нигде не разрушаешь, вот он и не разрушается у тебя.

время жизни переменной Арр равно времени жизни процесса, и все это время интерфейсная ссылка, которую ты получил, "живет" в этой переменной


 
Mx ©   (2005-08-05 16:28) [18]


> Digitman ©   (05.08.05 16:04) [17]
> время жизни переменной Арр равно времени жизни процесса

Это так, безусловно! Но когда приложение закрывается процесс таки завершается (правда тут Windows рулит, а не RTL, понимаю). Я хоче понять почему в случае с формой такого не было? Может ввиду ее явного разрушения в деструкторе Application?


 
Digitman ©   (2005-08-05 16:34) [19]


> когда приложение закрывается процесс таки завершается


так точно.

а раз завершается, то при этом немедленно и безусловно прекращают существование ВСЕ объекты, существовавшие когда-либо при "жизни" процесса в ЕГО контексте, в ЕГО адресном пространстве

и при этом неважно какой был процесс - консольный или GUI или сервис ..


 
Digitman ©   (2005-08-05 16:36) [20]


> вроде как счетчик ссылок при выходе должен был сам на нуль
> свалить


он и "свалил" ... в ходе исполнения неявного кода, который скрывается за последним оператором программы END.


 
Mx ©   (2005-08-05 16:36) [21]


> Digitman ©   (05.08.05 16:34) [19]

Но деструктор-то не выполняется, а в случае с GUI выполняется. Почему?


 
Digitman ©   (2005-08-05 16:38) [22]

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

или как ты это пытался определить ?


 
Mx ©   (2005-08-05 16:40) [23]


> Digitman ©   (05.08.05 16:38) [22]

Вначале поставил breakpoint, но потом подумал раз приложение закрывается можно не поймать. Тады сделал ShellExecute на web-страницу. Не сработало. Если явно App := nil, то все естественно ok.


 
Digitman ©   (2005-08-05 16:51) [24]


> Mx ©   (05.08.05 16:40) [23]


> можно не поймать


да, в ряде случаев можно и не поймать

просто заведи себе хорошую и полезную привычку оформлять код , работающий с интерф.объектами, след.образом

App := CreateAppObject;
try
 .. поработали с App ..
finally
 App := nil; //безусловно уничтожили
end;

и все недоразумения сразу исчезнут


 
Mx ©   (2005-08-05 16:56) [25]


> Digitman ©   (05.08.05 16:51) [24]

Привычку такую я со всем динамическим завел. Но ведь не всегда у нас код ограничен одним методом, верно. Сделаю явное присваивание. Все-равно, это отладочная прога.


 
Digitman ©   (2005-08-05 17:10) [26]


> ведь не всегда у нас код ограничен одним методом


да, не всегда.

но всегда можно найти решение ...

например, в дан.случае можно не заводить статическую переменную вообще, можно сделать так :

begin
with CreateAppObject do
try
  ...
except
  on E: Exception do
    WriteLn(...);
end;

//<- здесь объект уже неявно уничтожен
..
end.


 
Mx ©   (2005-08-05 17:17) [27]


> Digitman ©   (05.08.05 17:10) [26]

Прикол в том, что и так не работает! Я именно такую конструкцию применил в самый первый раз. Никакого деструктора не вызывается.


 
Digitman ©   (2005-08-05 17:49) [28]

потому что RefCount > 0 на этот момент


 
Digitman ©   (2005-08-05 17:50) [29]

точнее RefCount > 1


 
Digitman ©   (2005-08-05 18:22) [30]

дело в том что в методе TInterfacedObject.AfterConstruction() сч-к ссылок увеличивается на единицу, после чего (в момент запроса у этого объекта интерфейса и возврата его в кач-ве результата работы ф-ции CreateAppObject) для использования в WITH сч-к увеличивается еще на единицу

т.е. в варианте

 with CreateAppObject do begin
   messagebox(0, pchar(inttostr(getrefcount)), "", mb_ok or mb_setforeground);
//<- RefCount = 1 ! нужен вызов _release;
 end;

объект не будет разрушен

а в варианте

 messagebox(0, pchar(inttostr(CreateAppObject. getrefcount)), "", mb_ok or mb_setforeground);

все будет в порядке - объект будет успешно уничтожен


 
Mx ©   (2005-08-05 21:59) [31]

Значит [26] все-таки не совсем корректен. Я так и не понял почему в случае с формой разрушение происходит корректно? Какие есть соображения?


 
Бурундук ©   (2005-08-06 16:34) [32]

Кстати, советую почитать
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=759
(+ комментарии)


 
Mx ©   (2005-08-06 20:17) [33]


> Бурундук ©   (06.08.05 16:34) [32]

Спасибо за ссылку! Действительно, если произвести инициализацию в операторе var, то объект все-таки разрушается по завершении. Впредь буду знать.



Страницы: 1 вся ветка

Текущий архив: 2005.08.28;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.038 c
14-1123074511
Antonn
2005-08-03 17:08
2005.08.28
Держащим сайты на narod.ru


1-1123562256
ganda
2005-08-09 08:37
2005.08.28
Необходимо вызвать из DLL функцию вызова Excell


4-1120638026
Хинт
2005-07-06 12:20
2005.08.28
Как перебрать все элементы в окне?


1-1123429580
Андрей Молчанов
2005-08-07 19:46
2005.08.28
Как ловить сообщение, но не от формы, а от компонента


14-1123348504
lookin
2005-08-06 21:15
2005.08.28
Подсветка элементов в Code Insight