PMyType = ^TMyType
TMyType = record
X: Integer;
Y: Integer;
end;
*.DLL и другое...
Поделитесь опытом по некоторым вопросам:
1 - Какие эллементы (переменные и каких типов, константы, процедуры и т.п.) можно использовать в *.DLL, чтобы её можно было использовать в других языках программирования?
2 - Какие из этих эллементов можно делать экспортируемыми?
3 - Если я делаю библиотеку "A" и её используют приложения "B" и "C", то они работают с одной копией библиотеки или с разными? (Смысл обеспечить возможность общения между пиложениями через "A".)
4 - Если в разработке не использовать общения с системой, но усиленно работать с памятью и строками, то она получится кросс платформеной?
Сзаранее спасибо.
1. при передачи параметров приложение<->dll не используй объекты и строки (используй интерфейсы и pchar)..... от типов желательно тоже отказаться (используй указатели на типы)...
Указатель на тип - это как?
[QUOTE=verybadbug]используй интерфейсы и pchar[/QUOTE]
А не получится, что тогда проги с этой библиотекой, только под винду работать будут (просто на сколько я знаю эллементы DLL можно связывать, а можно встраивать, или я ошибаюсь?)?
Код:
PMyType имеет фиксированную длину и по суте является Pointer
2. чего не знаю - того не знаю....
2. Кроме процедур и функций ничего другого экспортировать не удасться.
3. Используются одна копия dll в памяти для обоих приложений, НО это относиться ТОЛЬКО для кода. Данные используються разные в адресных пространствах приложений B и С, так что нельзя. Используй для этого файлы, отображаемые в память, например.
2. Кроме процедур и функций ничего другого экспортировать не удасться.
[/QUOTE]
Не верно. Все зависит от способа загрузки длл в адресное пространство приложения.
[QUOTE=makbeth]
3. Используются одна копия dll в памяти для обоих приложений, НО это относиться ТОЛЬКО для кода. Данные используються разные в адресных пространствах приложений B и С, так что нельзя.[/QUOTE]
Насчет общих данных - тоже неверно. При необходимости создания разделяемых данных для всех приложений - это сделать можно непосредственно в длл.
А не получится, что тогда проги с этой библиотекой, только под винду работать будут (просто на сколько я знаю эллементы DLL можно связывать, а можно встраивать, или я ошибаюсь?)?[/QUOTE]
С длл ты только под винду используются. В ДОСе это делается по другому - в *nix технология схожа - но загрузить длл откомпилированную на винде вряд ли получится.
[/QUOTE]
[QUOTE=kot_]
При необходимости создания разделяемых данных для всех приложений - это сделать можно непосредственно в длл.[/QUOTE]
А расскажи пожалуста поподробней об этих моментах....
По подробнее лучше всеже ознакомится с литературой - так как тема достаточно обширна.
Если коротко - то существует два способа загрузки длл в память процесса - первый способ - динамический при помощи вызова АПИ-функции LoadLibrary. В данном случае как правило ты можешь использовать из длл только функции и процедуры, которые объявлены при помощи __declspec(dllexport) (возможно на делфи это может выглядеть по другому - ознакомься с хелпом). Правда и здесь есть ньюансы :) - можно экспортировать класс например - по крайней мере в С++, можно СОМ-объекты.
При статической загрузке все гораздо проще - при этом генерируется специальный файл в котором содержатся определения и адреса объектов длл. Этот файл линкуется вместе с экзешником и это позволяет экспортировать из длл практически любой объект - начиная от встроенных типов и заканчивая классами и т.п. Но опять же есть ньюансы :) связанные с различиями в компиляторах от разных производителей и разными языковыми средствами.
Если критично быстродействие и нужно работать с классами и структурами как правило всегда используют статическую линковку. Если важен размер исполняемого файла и .... короче при некоторых условиях - грузят динамически.
Про расшареную память - напишу позже - убегаю :)
мне кажется там имелся в виду линукс
[QUOTE=kot_]... при помощи __declspec(dllexport)... [/QUOTE]
function MyFunc(params); stdcall; external 'MyDll.dll' name 'MyFuncName';
по части COM.... если мне память не изменяет, для реализации этой возмижности необходимы винды2000 или выше...
[QUOTE=kot_]...Этот файл линкуется вместе с экзешником и это позволяет экспортировать из длл практически любой объект - начиная от встроенных типов и заканчивая классами и т.п. ...[/QUOTE]
но тогда отпадает сущность динам.связывания.... и потом обновились функции в dll (или их версии) - и снова компилить приложение надо....
[QUOTE=misha_turist]...Смысл обеспечить возможность общения между пиложениями через "A"... [/QUOTE]
а почему бы для этой цели не использовать memory-mapped files?
COM - уже лучше, но там опять надо знать что делать, и как делать (хотя на самом все довольно просто - через пакеты Delphi)
по части COM.... если мне память не изменяет, для реализации этой возмижности необходимы винды2000 или выше...
[/QUOTE]
Это СОМ+. СОМовскую технологию помоему (ИМХО, не помню) можно было уже юзать в 95 винде(имеется ввиду наличие СОМ-интерфейсов системы как таковых.)
[QUOTE=verybadbug]
но тогда отпадает сущность динам.связывания.... и потом обновились функции в dll (или их версии) - и снова компилить приложение надо....
[/QUOTE]
В мире нет бесплатного сыра. За все надо платить.
[QUOTE=verybadbug]
а почему бы для этой цели не использовать memory-mapped files?[/QUOTE]
это вопрос к автору вопроса :) Я говорю о возможности это сделать средствами компилятора. Нужно ли это делать вопрос другой.
Кстати есть необходимость описывать технологию - с учетом того что будет описываться как это сделать на С++ ?
Цитата:
Экспорт класса из dll в C++ - это по сути тот же экспорт процедур и функций - в Delphi это невозможно (особенности языка, хотя если поизвращаться... то можно - способы есть, хотя и не очень красивые).
Опять же смотря о каком способе загрузки мы говорим. И использование интерфейсных классов - это не совсем тоже самое что экспорт функций. Всмысле что механизмы другие.
по поводу COM в 2000 винде, -разве механизм создания COM объекта претерпел настолько конкретные изменения ? -по мне так все точно также как и в 9x b NT4. или я ошибаюсь ?
Речь идет о СОМ+ - технологии на основе СОМ. Она действительно появилась только в 2к и имеет ряд механизмов, которые собственно в СОМ отсутствуют.
Это как и что ??
Вы меня прям ими заволили))).
Но давайте я немножко уточню свой вопрос.
Я задумал сделать базу для интерпритатора (что то вроде WinApi, только в соответствующей области), работающую на уровне бинарных команд (не путайте пожалуста с командами процессора и т.п.), при этом я хочу, что бы мою разработку могли спользовать не только программисты Delphi, но и других языков. Сделать проект в виде DLL я решил из за того, что, по мойму, это самый простой способ изготовления проектов для разный языков.
Теперь по поводу взаимодействия разных приложений. Это задумывалось для того, что бы разные приложения, использующие мою разработку могли получать информацию о процессах интерпритации друг в друге. Предпологалась она, как очередной наворот и далеко не обязательна.
И будет обидно, если где-нибуть в конце работы выяснится, что всё накрывается медным тазом из за того, что где-то в начале я использовал то, что кто-нибуть не потдерживает.
Вот я и спросил, что можно использовать, а что нет??
P.S. Я пока концепцию продумываю, вот и изучаю в разных областях как что лучше сделать.
Для доступа к общим данным твоя dll (хотя для реализации не обязательно использовать dll) должна создать отображаемый в памяти файл и затем получить указатель на эту область памяти. На уровне WinAPI это CreateFileMapping и MapViewOfFile...
Код:
// dll
...
var
hMapFile: THandle;
ShareData: ^Integer;
...
const
VirtualFileName = 'MyFileName';
DataSize = SizeOf(Integer);
...
initialization
hMapFile := CreateFileMapping($FFFFFFFF, nil,
Page_ReadWrite, 0, DataSize, VirtualFileName);
if hMapFile = 0 then //ошибка создания файла
else ShareData := MapViewOfFile(hMapFile, File_Map_Write,
0, 0, DataSize);
...
finalization
UnmapViewOfFile(ShareData);
CloseHandle(hMapFile);
...
procedure SetShareData(I: Integer); stdcall;
begin
ShareData^ := I;
end;
...
...
var
hMapFile: THandle;
ShareData: ^Integer;
...
const
VirtualFileName = 'MyFileName';
DataSize = SizeOf(Integer);
...
initialization
hMapFile := CreateFileMapping($FFFFFFFF, nil,
Page_ReadWrite, 0, DataSize, VirtualFileName);
if hMapFile = 0 then //ошибка создания файла
else ShareData := MapViewOfFile(hMapFile, File_Map_Write,
0, 0, DataSize);
...
finalization
UnmapViewOfFile(ShareData);
CloseHandle(hMapFile);
...
procedure SetShareData(I: Integer); stdcall;
begin
ShareData^ := I;
end;
...