Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Я понимаю что подобное уже не раз спрашивали, но все же...


Страницы:   1 2

kull ©   (2002-10-28 18:51:00) 

Как передать строку (PChar) из Dll. Что бы вызывающее приложение могло ее кничтожить?

Я делаю так:

в dll-ке
....
function GetSubject: PChar; cdecl;
begin
Result := StrNew("subject");
end;

exports GetSubject;
....

в приложении
......

procedure TForm1.Button1Click(Sender: TObject);
var
H: HMODULE;
fn: function: PChar; cdecl;
S: PChar;
begin
H := LoadLibrary("d:\MyDLL.dll");
fn := GetProcAddress(H, "GetSubject");
S := fn;
StrDispose(S);//Вот здесь валится с сообщением "Invalid pointer operation"
end;


Помогите идиоту, что-то я под вечер совсем не соображаю.


panov   (2002-10-29 09:36:00) [21]

>kull © (28.10.02 23:37)

Пример:

1. Модуль библиотеки:

library strutil;

uses
SysUtils;

var
tPChar: PChar;

function RetString: Pchar;stdcall;
var
i : Integer;
begin
ReAllocMem(tPChar,1024);
for i := 0 to 1022 do tPChar[i] := "$";
Result := tPChar;
end;

procedure FreeStr;stdcall;
begin
FreeMem(tPChar);
end;

exports
RetString,
FreeStr;
end.


2. Модуль для работы с библиотекой:

unit strutil;

interface
uses Windows,sysutils;

type ELibLoadError = class(Exception);
var RetString: function: Pchar;stdcall;
var FreeStr: procedure;stdcall;
var hLib: hWnd;

procedure LoadLib;
procedure UnloadLib;

implementation

procedure LoadLib;
begin
hLib := LoadLibrary(PChar("strutil.dll"));
if (hLib=0) then
begin
raise ELibLoadError.Create("


Юрий Зотов   (2002-10-29 08:52:00) [22]

PChar - он и есть PChar, все равно в конце строки будет ноль. Так что никаких дополнительных функций не требуется - длина строки определяется автоматически.

Так же и в API. Например, никто не заставляет обязательно вызывать GetWindowTextLength перед GetWindowText. А во многих случаях функций, подобных GetWindowTextLength просто нет.


kull   (2002-10-29 01:23:00) [23]


> Юрий Зотов © (28.10.02 23:57)

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


Юрий Зотов   (2002-10-28 23:57:00) [24]

Поступайте так же, как принято в API - выделяет и освобождает память вызывающая сторона, а вызываемая только заполняет переданный ей готовый (уже размещенный) буфер. И все будет тип-топ.


kull   (2002-10-28 23:37:00) [25]


> panov © (28.10.02 21:49)
> Переменную объяви глобальной в DLL...

В каком смысле? Что-то я не понимаю...

Мне кажется что проблемма в способе выделения и освобождения памяти.
Вот если выделять с помощью VirtualAlloc, а освобождать с помощью VirtualFree, то все работает нормально.

Задача в том, чтобы DLL можно было написать на любом языке, например C++. Может еще есть способы работы с памятью в Delphi, такие чтоб стыковались с C++?


panov   (2002-10-28 21:49:00) [26]

Переменную объяви глобальной в DLL...


LongIsland   (2002-10-28 20:53:00) [27]

Тогда я совсем ничего не понимаю... :-(


kull   (2002-10-28 20:32:00) [28]

Может я совсем ничего не понимаю, но если сделать следующее:

DLL:

...
procedure GetSubject(var P: Pointer); cdecl;
begin
GetMem(P, 100);
end;

exports GetSubject;



Application:
...

procedure TForm1.Button1Click(Sender: TObject);
var
H: HMODULE;
fn: procedure(var P: Pointer); cdecl;
P: Pointer;
begin
H := LoadLibrary("d:\MyDLL.dll");
fn := GetProcAddress(H, "GetSubject");
fn(P);
FreeMem(P);
end;



Возникает та же ситуация.


LongIsland   (2002-10-28 20:18:00) [29]

То ли я торможу, то ли ничего не понимаю, но память выделяется для fn. S нужно прописать по адресу fn. Поправьте меня и я с радостью отправлюсь читать доки:-)


kull   (2002-10-28 20:08:00) [30]

Как не выделил? А StrNew ?


LongIsland   (2002-10-28 19:24:00) [31]

ИМХО: Вы не выделили память и пытаетесь ее освбодить, если я что-то в чем-то соображаю:-)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо