sharedMemory的这个限制是实际的吗?我已经传递到DLL字符串长度约370个字符和DLL读取它没有问题。
我是在问,因为我从DLL返回PChar到EXE程序。在DLL中我使用GetMem()函数,在EXE程序中我使用FreeMem()函数,
我可以得到Acces违规的写作-我调用导出的函数,在这里我使用构造函数,它可能崩溃。
当我从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;发布于 2015-12-29 12:26:11
主机可执行文件和DLL有两个独立的内存管理器副本。
要像这样共享内存,您需要使用共享内存管理器。
作为另一种选择,您可以重新设计API,以便只在一边进行分配和取消分配,无论是在DLL中(公开要释放的函数)还是在主机可执行文件中(公开函数以返回所需的缓冲区大小,并允许调用方分配和释放)。
https://stackoverflow.com/questions/34510753
复制相似问题