Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  08:06[Войти] | [Зарегистрироваться]
Ответ на вопрос № 42501

17-05-2006 01:30
Здравствуйте.

При использовании интерфейсов для доступа к классам из DLL также необходимо придерживаться правил (для DLL) при работе, например, со строками?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

18-05-2006 02:37
Будет ли являться выходом из данной "проблемы" замена типа string на WideString?
Будет, так как по сути используется тот же "ShareMem", только от Microsoft.

18-05-2006 02:04 | Сообщение от автора вопроса
Будет ли являться выходом из данной "проблемы" замена типа string на WideString?

18-05-2006 02:01
Нет, строки без ShareMem корректно не передаются ни в обычных процедурах, ни в методах класса/интерфейса.

18-05-2006 01:50 | Сообщение от автора вопроса
Хочется сделать какой-нибудь Вывод в данной дискуссии:

Опишу небольшой примерчик. Имеется класс, который описан в DLL и реализует некий интерфейс. У класс есть поле FOnTagEvent: TX12TagsEvent, которое предназначено для хранения ссылки на "объектную процедуру" для обрабоки некоторого события (данный класс изначально был компонентом, и соответсвенно наследовался от TComponent, но при переводе его в DLL наследник соответсвенно стал TObject, а точнее TInterfacedObject)! Пример типа метода для обработки события:

TX12TagsEvent = procedure (const Sender: TObject; const TagName: String; var ReplaceText: string) of object;


Соответсвенно для данного класса описан интерфейс с описанием основных методов и свойств.
Меня интересует вопрос, корректно ли будет передаваться параметр ReplaceText: string при обработке события OnTagEvent обратно в класс, который находится в DLL и доступен, соотвественно, чере _интерфейс_???

Если из описания примера смысл не ясен, прошу простить...

18-05-2006 01:23
А типа соглашения о вызове у методов интерфейса указать, разве не прокатит??  safecall, OleVariant, WideString... и поехали - "Белое не надевать", делфийские стринги и обьекты не передавать..
Или мы о разном толкуем?


Да, о разном. Я, вообще-то, имел ввиду вот что: пусть у нас есть интерфейс с методами A и B, а у класса, который его реализует - поле FS:string. И пусть в методе A есть код FS:='ABC', а в B - FS:=FS+'CDE'. Тогда, если мы вызываем из программы метод A, потом передаём интерфейс в DLL и вызываем там метод B, получается, что в DLL перераспределяется память, выделенная в основной программе.

Однако по зрелому размышлению я понял, что я тут неправ: то, какой менеджер памяти будет использован при работе B, определяется на этапе компиляции и не зависит от того, откуда B вызывается. Следовательно, перераспределением памяти в данном случае будет заниматься тот же менеджер, который её выделил, и, следовательно, проблем не будет.

Сейчас я не могу придумать ситуацию, когда передача в DLL интерфейсов могла бы привести к тем проблемам, которые решаются с помощью ShareMem. Весьма вероятно, что таких ситуаций вообще не существует, и интерфейсы можно безопасно передавать и без ShareMem.

18-05-2006 00:08 | Сообщение от автора вопроса
Мне кажется, что соглашения о вызове методов могут гарантировать "корректный" обмен параметрами между модулями не более. А вот пробдемы перераспределения памяти из одного модуля в другом остаются теже. Или я все же не так что то понимаю?

17-05-2006 09:41 | Комментарий к предыдущим ответам
Ребяты! Может я торможу, но если уж делать нормальные _интерфейсы_ нормальным путем, то никаких ShareMem не нужно.

To Антон Григорьев:
>>>что его методы при своей работе не перераспределяют выделенную ранее память

А типа соглашения о вызове у методов интерфейса указать, разве не прокатит??  safecall, OleVariant, WideString... и поехали - "Белое не надевать", делфийские стринги и обьекты не передавать..
Или мы о разном толкуем?

17-05-2006 04:12
А ты попробуй вместо string - widestring
http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1202
http://www.delphikingdom.ru/asp/articles_forum.asp?ArticleID=1202

17-05-2006 04:08 | Сообщение от автора вопроса
Интересная тема... :)

17-05-2006 03:46
Ну есть всякие способы обойтись без библиотеки, можно например поставить http://fastmm.sourceforge.net/ или использовать вместо ShareMem такой модуль (не тестировал):

unit FastShareMem;
interface
var
  GetHeapStatus:function:THeapStatus;
  GetAllocMemCount:function:Integer;
  GetAllocMemSize:function:Integer;

implementation
uses
  Windows;

const
  ClassName='_com.codexterity.fastsharemem.dataclass';

type
  TFastSharememPack=record
    MemMgr:TMemoryManager;
    GetHeapStatus:function:THeapStatus;
    GetAllocMemSize:function:Integer;
    GetAllocMemCount:function:Integer;
  end;

function _GetAllocMemCount:Integer;
begin
  Result:=System.AllocMemCount;
end;

function _GetAllocMemSize:Integer;
begin
  Result:=System.AllocMemSize;
end;

var
  MemPack:TFastSharememPack=(GetHeapStatus:System.GetHeapStatus;GetAllocMemSize:_GetAllocMemSize;GetAllocMemCount:_GetAllocMemCount);
  WndClass:TWndClass=(style:CS_GLOBALCLASS;lpfnWndProc:@MemPack;lpszClassName:ClassName);
  OldMemMgr:TMemoryManager;
  IsFirst:Boolean;

initialization
  IsFirst:=not GetClassInfo(HInstance,ClassName,WndClass);
  if IsFirst then begin
    GetMemoryManager(MemPack.MemMgr);
    GetHeapStatus:=System.GetHeapStatus;
    GetAllocMemCount:=@_GetAllocMemCount;
    GetAllocMemSize:=@_GetAllocMemSize;
    WndClass.hInstance:=hInstance;
    if RegisterClass(WndClass)=0 then begin
      MessageBox(0,'Shared Memory Allocator setup failed: Cannot register class.','FastShareMem',MB_ICONERROR or MB_TASKMODAL);
      Halt;
    end;
  end
  else begin
    GetMemoryManager(OldMemMgr);
    GetHeapStatus:=TFastSharememPack(WndClass.lpfnWndProc^).GetHeapStatus;
    GetAllocMemCount:=TFastSharememPack(WndClass.lpfnWndProc^).GetAllocMemCount;
    GetAllocMemSize:=TFastSharememPack(WndClass.lpfnWndProc^).GetAllocMemSize;
    SetMemoryManager(TFastSharememPack(WndClass.lpfnWndProc^).MemMgr);
  end;
finalization
  if IsFirst then
    UnregisterClass(ClassName,HInstance)
  else
    SetMemoryManager(OldMemMgr);
end.


17-05-2006 03:13 | Сообщение от автора вопроса
Если использовать ShareMem значит придется таскать с программой еще и библиотеку дополнительную.
Спасибо Антон.

17-05-2006 02:59
Нет, если уж вы начали передавать классы, то позаботьтесь и об использовании ShareMem - классы могут перераспределять память и помимо использования вами свойств.

17-05-2006 02:33 | Сообщение от автора вопроса
Значит если в классе изначально были свойства типа String, то соотвественно при переносе класса в DLL желательно свойства переопределить в тип, напрмер, PChar, чтоб передавать адрес на выделенный программой буфер памяти под строку, и соотвествено также возвращать данные из DLL?

17-05-2006 02:24
Лучше придерживаться, хотя иногда можно обойтись и без них. Опасность представляет та ситуация, когда память, выделенная в одном модуле, освобождается или перераспределяется в другом. А класс - это чёрный ящик, в общем случае вы не можете гарантировать, что его методы при своей работе не перераспределяют выделенную ранее память. Это не зависит от того, используются ли для доступа к объекту интерфейсы, или нет.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Однажды, в студеную зимнюю пору я из лесу вышел, был сильный ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования