Где и когда освободить PWideChars, отправленные на внешнюю DLL - PullRequest
2 голосов
/ 26 ноября 2010

Я выделяю память для нескольких PWideChar в моем главном исполняемом файле

var
  pwcValor: PWideChar;
begin
  pwcValor := AllocMem( sizeof(WideChar) * Succ(Length(pValor)));
  StringToWideChar(pValor, pwcValor, Succ(Length(pValor)));
  pMetodo(pCodigo, pCodigoParametro, pwcValor);

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

  • Где (на моем exe или моей dll) я должен вызывать FreeMem по этим переменным?FreeMem по этим переменным?
  • Когда я могу (или я должен) вызвать FreeMem для этих переменных?

Если я вызываю их во внешней DLL (которая также является моей), я получаю нарушения прав доступа, когда яПопробуйте выгрузить из памяти библиотеку DLL.
Tks

РЕДАКТИРОВАТЬ

Что-то, что я забыл спросить.И наоборот?Я так возвращаю параметры из моей DLL в EXE, поэтому PWideChars распределяются по DLL.Итак, я должен был бы освободить их в DLL, верно?Но я, вероятно, все еще буду использовать их на EXE.Должен ли я предварительно выделить файл EXE, отправить в DLL указатель и заполнить ли он DLL в этих случаях?Или просто скопируйте в EXE возвращенного параметра, чтобы я мог безопасно освободить его в DLL?

Ответы [ 3 ]

3 голосов
/ 26 ноября 2010

В конечном счете, это зависит от дизайна используемых вами DLL.Тем не менее, я бы сказал, что если не задокументировано иначе, можно безопасно освободить ресурсы, как только функция DLL вернется.Я бы даже предложил вам это сделать.В любом случае вы должны сделать это, чтобы избежать утечек памяти.

Что касается последнего предложения, DLL и вызывающего EXE-файла, хотя они оба являются Delphi-кодом, они используют разные менеджеры памяти, поэтому вы не можете в свободной памяти DLL, выделеннойEXE.

2 голосов
/ 26 ноября 2010

Относительно освобождения:

Здесь возможны различные решения:

  • Ваш исполняемый файл может выделить буфер, который затем будет заполнен dll;
  • Ваша dll может экспортировать еще одну функцию, скажем, FreeString.Exe должен вызывать его каждый раз, когда заканчивается строка;
  • Вы можете использовать простой тип WideString.Этот тип строк использует системный менеджер памяти, который одинаков для exe и dll.

Лично я рекомендую вам последний вариант.

0 голосов
/ 26 ноября 2010

Если у вас есть строковая переменная Delphi и вы используете D2009 или новее, так что PChar отображается в PWideChar, то вы можете просто вызвать вашу функцию с помощью pMetodo(pCodigo, pCodigoParametro, PChar(pValor)).Затем внутри вашей DLL вы берете копию строки, объявляя строковую переменную и просто присваивая строку.Например, код DLL будет выглядеть следующим образом:

procedure pMetodo(pwcValor: PChar);
var
  pValor: string;
begin
  pValor := pwcValor;
  ...
end;

Код, который у вас есть, довольно излишне сложен.Делая это так, как я предлагаю, избегает использования каких-либо явных процедур выделения памяти.Если вы хотите написать код на C, тогда зачем использовать Delphi !!; -)

Если вы хотите быть более явным, вы можете написать PWideChar, а не PChar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...