Delphi DLL PChar
Delphi DLL PChar
sharedMemory 的这个限制是实际的吗?
我已将大约 370 个字符的字符串长度传递给 DLL,并且 DLL 读取它没有问题。
我在问,因为我return PChar 从DLL 到EXE 程序。
在 DLL 中我使用 GetMem() 函数,在 EXE 程序中我使用 FreeMem() 函数,并且
我可以得到写入访问冲突 - 我调用导出函数,我在其中使用构造函数,它可能会崩溃。
当我从 Exec 中删除 FreeMem 时,此 AV 未显示。也不总是显示,它取决于 PChar 变量中的字符:
255 x a - 可以通过
但是 ąłćłąłłąłść łąśććłłć :// 可能会崩溃。
示例 - 在 DLL 中创建消息:
function TPDF.wiadomosciBledow(kod: kodyBledow): TWynik;
var
tmp: string;
begin
case kod of
kbOK: tmp := ''; //natomiast tutaj tego nie zauważyłem
kbBladLogowania: tmp := 'Nie można zalogować się do serwera Archiwum';
kbBrakAdresSerwera: tmp := 'Wprowadź adres serwera, np.: http://arch.lpwik:5984/';
kbBrakDanychJSON: tmp := 'Wprowadź dane do logowania w formacie JSON - API _session';
kbBladPobrania: tmp := 'Nie można pobrać wskazanego pliku';
kbBrakURL: tmp := 'Wprowadź adres URL do pobrania, np.: http://arch.lpwik:5984/baza/dok_1/zal_1.pdf';
kbBrakProtokolu: tmp := 'Wymagane jest wprowadzenie protokołu http:// lub https://'; //z jakiegoś powodu wprowadzenie tutaj dwóch slashy // powoduje błąd
end;
result.kod := ord(kod);
GetMem(result.wiadomosc, sizeof(WideChar) * Length(tmp) + 1);
result.wiadomosc := StrPCopy(result.wiadomosc, tmp);
end;
并在 Exec freemem 中:
procedure TOkno.pokazPDFClick(Sender: TObject);
var
wejscie: TZalacznik;
wyjscie: TWynik;
t: string;
begin
if @wyswietlPDF = nil then exit();
{inicjalizacja pamięci - widechar na jeden znak potrzebuje 2 bajty}
GetMem(wejscie.pelnyAdresURL, 2 * Length(adresURL.Text) + 1);
{przekopiowanie danych}
StrPCopy(wejscie.pelnyAdresURL, adresURL.Text);
{wywołanie metody z DLL}
wyjscie := wyswietlPDF(wejscie); //dll function
{wyświetlenie wyniku w grupie}
wynikKod.Caption := IntToStr(wyjscie.kod);
wynikWiadomosc.Caption := wyjscie.wiadomosc;
{zwalnianie przydzielanej pamięci}
FreeMem(wejscie.pelnyAdresURL);
FreeMem(wyjscie.wiadomosc); //if commented I do not have AV
end;
主机可执行文件和 DLL 有两个独立的内存管理器副本。
要像这样共享内存,您需要使用 shared memory manager。
作为替代方案,您可以重新设计 API 以便分配和解除分配都只发生在一侧,要么都在 DLL 中(公开要解除分配的函数),要么都在主机可执行文件中(将函数暴露给 return 所需的缓冲区大小,并让调用者分配和解除分配)。
sharedMemory 的这个限制是实际的吗? 我已将大约 370 个字符的字符串长度传递给 DLL,并且 DLL 读取它没有问题。
我在问,因为我return PChar 从DLL 到EXE 程序。 在 DLL 中我使用 GetMem() 函数,在 EXE 程序中我使用 FreeMem() 函数,并且
我可以得到写入访问冲突 - 我调用导出函数,我在其中使用构造函数,它可能会崩溃。
当我从 Exec 中删除 FreeMem 时,此 AV 未显示。也不总是显示,它取决于 PChar 变量中的字符:
255 x a - 可以通过 但是 ąłćłąłłąłść łąśććłłć :// 可能会崩溃。
示例 - 在 DLL 中创建消息:
function TPDF.wiadomosciBledow(kod: kodyBledow): TWynik;
var
tmp: string;
begin
case kod of
kbOK: tmp := ''; //natomiast tutaj tego nie zauważyłem
kbBladLogowania: tmp := 'Nie można zalogować się do serwera Archiwum';
kbBrakAdresSerwera: tmp := 'Wprowadź adres serwera, np.: http://arch.lpwik:5984/';
kbBrakDanychJSON: tmp := 'Wprowadź dane do logowania w formacie JSON - API _session';
kbBladPobrania: tmp := 'Nie można pobrać wskazanego pliku';
kbBrakURL: tmp := 'Wprowadź adres URL do pobrania, np.: http://arch.lpwik:5984/baza/dok_1/zal_1.pdf';
kbBrakProtokolu: tmp := 'Wymagane jest wprowadzenie protokołu http:// lub https://'; //z jakiegoś powodu wprowadzenie tutaj dwóch slashy // powoduje błąd
end;
result.kod := ord(kod);
GetMem(result.wiadomosc, sizeof(WideChar) * Length(tmp) + 1);
result.wiadomosc := StrPCopy(result.wiadomosc, tmp);
end;
并在 Exec freemem 中:
procedure TOkno.pokazPDFClick(Sender: TObject);
var
wejscie: TZalacznik;
wyjscie: TWynik;
t: string;
begin
if @wyswietlPDF = nil then exit();
{inicjalizacja pamięci - widechar na jeden znak potrzebuje 2 bajty}
GetMem(wejscie.pelnyAdresURL, 2 * Length(adresURL.Text) + 1);
{przekopiowanie danych}
StrPCopy(wejscie.pelnyAdresURL, adresURL.Text);
{wywołanie metody z DLL}
wyjscie := wyswietlPDF(wejscie); //dll function
{wyświetlenie wyniku w grupie}
wynikKod.Caption := IntToStr(wyjscie.kod);
wynikWiadomosc.Caption := wyjscie.wiadomosc;
{zwalnianie przydzielanej pamięci}
FreeMem(wejscie.pelnyAdresURL);
FreeMem(wyjscie.wiadomosc); //if commented I do not have AV
end;
主机可执行文件和 DLL 有两个独立的内存管理器副本。
要像这样共享内存,您需要使用 shared memory manager。
作为替代方案,您可以重新设计 API 以便分配和解除分配都只发生在一侧,要么都在 DLL 中(公开要解除分配的函数),要么都在主机可执行文件中(将函数暴露给 return 所需的缓冲区大小,并让调用者分配和解除分配)。