Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Вниз

Так, а если общение через интерфейс, но интерфейс в 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.051 c
1-1123428673
Eraser
2005-08-07 19:31
2005.08.28
Ошибка в коде. Порча данных


3-1121671971
TAN_K
2005-07-18 11:32
2005.08.28
QuicRep - форматирование вычисляемого поля


14-1122964668
dmitry99
2005-08-02 10:37
2005.08.28
День Десантника.


4-1120747792
_vvv_
2005-07-07 18:49
2005.08.28
Windows авторизация


14-1123053638
ocean
2005-08-03 11:20
2005.08.28
Совместимы ли сила и ум?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский