Форум: "Основная";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];
ВнизПеременные в DLL Найти похожие ветки
← →
LAnd © (2004-05-07 21:11) [0]Подскажите пожалуйста! У меня в DLL есть переменная ErrorList :TStringList, эту библиотеку я пишу на Делфи, затем я ее поключаю в Borland Builder и мне нужно как-то узнать значение переменной, что дописать в библиотеке чтобы можно было использовать эту переменную?
← →
Alex Konshin © (2004-05-07 21:15) [1]Я бы на твоем месте добавил бы две функции в DLL:
geterrorcount : DWORD
geterror( index : DWORD ) : PChar
← →
Mim1 © (2004-05-07 21:30) [2]Alex Konshin © (07.05.04 21:15) [1]
Можно на всякий пожарный довать зарание подготовленый буфер
geterror(index:DWORD; buffer:pchar; bufsize:integer);
← →
LAnd © (2004-05-07 21:30) [3]Спасибо, как я до этого не додумался... Все же очень просто :)
← →
Alex Konshin © (2004-05-07 21:34) [4]Зачем буфер? Мы же эту строку даем и ясно, сколько она там будет жить и кто ее будет убивать. Поэтому вполне можно вернуть и указатель.
← →
default © (2004-05-07 21:34) [5]можно COM-интерфейс предоставить
← →
Alex Konshin © (2004-05-07 21:36) [6]Единственное (но это и ежу понятно) использующий эту строку не должен ее менять.
Это безопасно, если знаешь, что делаешь.
← →
Alex Konshin © (2004-05-07 21:38) [7]Из DLL COM интерфейс? А зачем? Чтоб в используемом приложении еще и инициализировать COM и преобразовывать строки в BSTR? Чего на ровном месте огород городить?
← →
Mim1 © (2004-05-07 21:38) [8]Имхо лучше не знать что делаеш [2] и жить спокойно не думая о подобных вещах [4][6].
← →
default © (2004-05-07 21:41) [9]Alex Konshin © (07.05.04 21:38) [7]
согласен если нужно несколько ф-ий предоставить, а так можно
(только ради того чтобы работа с TStringList была как с объектом, хотя эту цель можно и без COM достигнуть...)
← →
Alex Konshin © (2004-05-07 21:48) [10]Mim1 © (07.05.04 21:38) [8]
Имхо лучше не знать что делаеш [2] и жить спокойно не думая о подобных вещах [4][6].
Палку перегибать не надо.
В данной ситуации вполне достаточно и безопасно то, что я написал. Те требования - само собой разумеющиеся.
← →
default © (2004-05-07 22:02) [11]чтобы не бояться за изменение строки и не запрашивать размер строки чтобы выделить буфер и передать его в DLL для записи копии строки можно в запросе на строку передавать адрес ф-ции выделения памяти в вызывающем коде тогда вызванный код сам определит сколько нужно выделить выделит память с использованием менеджера вызывающего кода и он же решить когда убивать строку самостоятельно и сможет её менять не нарушая данных реального TStringList-а
← →
Alex Konshin © (2004-05-07 22:10) [12]Если он уж так боится изменить эту строку, то он может скопировать строку в буфер сразу после получения.
Make it simple.
В твоем решении еще понадобится куча лабуды не несущей никакого реального улучшения. Проверки размеров буфера, выделение/освобождение памяти и ради чего?
Тогда уж заодно еще и multithread поддерживай, а то вдруг во время копирования этот самый stringlist кто-нибудь убьет.
Ну давайте не будем разводить демагогию на ровном месте.
← →
default © (2004-05-07 22:19) [13]Alex Konshin © (07.05.04 22:10) [12]
"Проверки размеров буфера, выделение/освобождение памяти и ради чего?" откуда? типа GetString(MemProc: TMemProc, ...
TMemProc = function(MemSize: Cardinal): Pointer;
никакой лабуды...
когда вызывающему коду задалбается эт строка он просто сделает что-то типа FreeMem(StringPointer)
← →
Alex Konshin © (2004-05-07 22:23) [14]Вот и вопрос: а на зачем?
← →
default © (2004-05-07 22:49) [15]Alex Konshin © (07.05.04 22:23) [14]
чтобы не заставлять польз-ля DLL помнить о всяких там деталях(выделения буфера для строки перед изменением полученной строки)
и самому в нужный момент осв-ать строку
← →
Mim1 © (2004-05-07 22:53) [16]> Если он уж так боится изменить эту строку, то он может
> скопировать строку в буфер сразу после получения.
Интересно, ведь есть api функция getwindowtext котора заполняет ваш буфер а не говорит "вы типо сокпируйте возвращенную строку а то вдруг она умрет".
Для определения длины строки ее можно вызвать с nil в качестве параметра.
Что касается сложности то ее нет, просто используйте strlcopy и будет вам счасте.
Вот пример зкспортируемой функции.Function geterror(index:DWORD; buffer:pchar; bufsize:integer):integer;
var s:string;
ls:integer;
begin
s := struinglist[i];
ls := length(s);
if (buffer = nil) or (bufsize < ls+1) then
begin
result := ls+1;
exit;
end;
strlcopy(buffer,pchar(s),ls);
result := -1;
end;
А вот так будем получать эту строку
var
s:integer;
p:pchar;
begin
s := geterror(15,nil,0);
getmem(p,s);
geterror(15,p,s);
end;
← →
Alex Konshin © (2004-05-07 23:04) [17]О господи, затеяли теологические споры.
Я знаю как это сделать.
Я не вижу необходимости это делать.
← →
default © (2004-05-07 23:07) [18]s := geterror(15,nil,0);
getmem(p,s);
geterror(15,p,s);
можно сделать всё это за один вызов...)))
← →
Alex Konshin © (2004-05-07 23:08) [19]default © (07.05.04 22:49) [15]
Alex Konshin © (07.05.04 22:23) [14]
чтобы не заставлять польз-ля DLL помнить о всяких там деталях(выделения буфера для строки перед изменением полученной строки)
и самому в нужный момент осв-ать строку
В C/C++ тебе по любому нужно будет выделять такой буфер, если ты собрался менять строку.
И не надо придумывать какие-то умозрительные возможности, вы перечитайте вопрос и попробуйте найти хоть какое-то разумное объяснение вашей потребности изменить сообщение ошибке.
← →
default © (2004-05-07 23:09) [20]Mim1 © (07.05.04 22:53) [16]
как удобней?
"s := geterror(15,nil,0);
getmem(p,s);
geterror(15,p,s); "
или StringPointer := GetString(@MemProc, Index: Integer);
if StringPointer <> nil then ...
...
FreeMem(StringPointer)
и никаких геморов для юзера... типа вызови сначала то потом то...
← →
default © (2004-05-07 23:11) [21]Alex Konshin © (07.05.04 23:08) [19]
ёлки палки... да буфер этот выделит код в DLL...никакой нагрузки для юзера...пример выозва есть повыше
← →
Alex Konshin © (2004-05-07 23:14) [22]Зачем? Я много чего делать умею. Может еще и в unicode перевести для надежности? Ну вы соизмеряйте задачу и решение.
Очень поспорить хочется?
← →
default © (2004-05-07 23:20) [23]Alex Konshin © (07.05.04 23:14) [22]
неа наоборот уже закончить это хочется...
тут, конечно, всё зависит от того хочет юзер получить копию или оригинал(если изменять не собирается(чтобы память зря не выделять))
наверно лучше было бы сделать так
function GetString(Index: Integer; CreateNewString: Boolean = False; MemProc: TMemProc = nil): PChar;
и в зависимости от флага создавать копию или передавать оригинал...согласны?
← →
Alex Konshin © (2004-05-07 23:27) [24]Зачем?
Если мне нужна будет копия - я легко ее сам создам. Я практически уверен, что она не понадобится. Так зачем содавать код, который не будет использоваться?
← →
default © (2004-05-07 23:29) [25]Alex Konshin © (07.05.04 23:27) [24]
если есть такая уверенность то конечно
мы ж не знаем для чего она автору смотреть на неё или изменять
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.034 c