Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
Внизтип PCHAR и ACCESS Найти похожие ветки
← →
Stas © (2004-04-28 10:16) [0]Есть DLL написана на Delphi, Функция возвращает тип PCHAR:
Function GetDefUser (FieldName:PChar):PCHAR; stdCall;Export;
В Delpi"ийских прогах работает правильно. В Access дописывает до результата еще знаки типа: "my string ....." (вместо точек квадраты). Что можно сделать ?
← →
Digitman © (2004-04-28 10:29) [1]отказаться от ф-ции в пользу процедуры
2-м параметром типа PChar получать из Access подготовленную им и переданную ByVal-строку заранее известной длины, в которую и записывать результат
← →
Stas © (2004-04-28 10:54) [2]Спасибо. Я заметил что к стоке добавляется 5 символов. Решил их просто обрезать.
← →
evvcom © (2004-04-28 10:56) [3]Решение, достойное дилетанта.
← →
Stas © (2004-04-28 11:45) [4]evvcom © (28.04.04 10:56) [3]
Согласен. Есть другие предложения ?
← →
Digitman © (2004-04-28 11:54) [5]
> Stas © (28.04.04 11:45) [4]
предложение тебе уже было сделано в [1]
это - единственно корректный вариант взаимодействия двух упомянутых сред в части возврата строк
← →
Digitman © (2004-04-28 11:56) [6]можно еще, конечно, переделать DLL в сервер автоматизации, тогда можно будет результат передавать как OleVariant
← →
Stas © (2004-04-28 12:11) [7]Для реализации этого варианта.
Нужно Возвращать 2 параметра, 1- длинна строки, 2- строка. После этого нужно обработать полученную строку строку.
Но если значение 1 параметра всегда меньше на 5 длинны строки, то для чего это нужно ? Если будут замечены проблемы всегда можно переделать.
← →
Digitman © (2004-04-28 12:23) [8]
> Stas © (28.04.04 12:11) [7]
давай-ка, чтобы не быть голословными, приводи полный код ф-ции ..
← →
Stas © (2004-04-28 12:27) [9]Вот ее полный код.
Function GetDefUser (FieldName:PChar):PCHAR; stdCall;Export;
begin
Result:=GetDefUserA (FieldName);
end;
Function GetDefUserA (const FieldName:PChar):PChar;
Var FN,SQL:String; A:PChar;
begin
FN:=string(FieldName);
if not DataSetDefUs.Active then
begin
SQL:="SELECT * FROM dbo.[t77x01gUSERA] WHERE KODOTD="+IntToStr(Otdel)+" and KODUS="+IntToStr(User);
DataSetDefUs.SQL.Text:=SQL;
DataSetDefUs.Open;
end;
Result:= StrNew(PCHAR(DataSetDefUs.FieldByName(FN).AsString));
end;
← →
Digitman © (2004-04-28 14:11) [10]
> Stas © (28.04.04 12:27) [9]
вот ты в StrNew() выделил память под возвращаемую строку, использовав для этого менеджер памяти Делфи
ты не задумывался над вопросом, кто и как ее должен и будет ли освобождать ? Access епонятия не имеет ни о каких иных менеджерах памяти кроме своего собственного ! В результате при каждом обращении к ф-ции у тебя будт происходить утечка памяти
← →
Stas © (2004-04-28 15:03) [11]Digitman © (28.04.04 14:11) [10]
Что нужно сделать ?
Просто прировнять не получается.
← →
Stas © (2004-04-28 15:11) [12]Если Сделать так ?
Function GetDefUser (FieldName:PChar):PCHAR; stdCall;Export;
VAr A:Pchar;
begin
A:=GetDefUserA (FieldName);
Result:=A;
StrDispose (A);
end;
← →
Digitman © (2004-04-28 15:39) [13]
> Stas © (28.04.04 15:11) [12]
ну у тебя с головой не в порядке что-то, видимо)
ну вот ты сделал StrDispose() - ну откуда же Access возьмет данные, если памzть, их содержащую, ты освободил собственными руками ?!
в тридцать лохматый раз говорю тебе - память под возвращаемый результат должен распределять/освобождать сам Access ! и передавать тебе лишь готовую ссылку на эту память ! твоя же задача в DLL - просто заполнить эту память некими строковыми данными, а остальное тебя не должно волновать ! и все будет корректно)..
именно об этом я тебе и сказал, когда рекомендовал отказаться от ф-ции в пользу процедуры, 2-ым параметром которой Access должен передать строковую "заготовку" фикс.длины для того чтобы твоя DLL могла ее заполнить, и при том - безо всяких заморочек с распределением памяти ...
← →
evvcom © (2004-04-28 15:39) [14]Всё неправильно! Посмотри как написаны подобные API-функции. Например,
function GetDefUser(FieldName: PChar; UserName: PChar; MaxLength: Integer): Integer; stdcall;
В вызывающей проге выделяешь MaxLength байт для UserName, и передаешь. А в функции заполняешь максимум MaxLength байт, а возвращаешь, хочешь сколько реально заполнил, а хочешь действительную длину UserName (вдруг мало выделил).
← →
evvcom © (2004-04-28 15:41) [15]А потом в вызывающей проге после использования UserName сам же и освобождаешь память, которую выделял.
← →
WebErr © (2004-04-28 15:51) [16]
> evvcom © (28.04.04 15:39) [14]
Именно.
А для выделения памяти под PChar рекомендую использовать GetMem, с последующим FreeMem.
Хотя Access поймёт и API функции Malloc и Free, которые Вы и можете вызывать в самой процедуре.
← →
Stas © (2004-04-28 15:52) [17]Digitman © (28.04.04 15:39) [13]
Ты мне советуешь из Access передать длинну строковой переменной, которая Access"у неизвестна ?
← →
WebErr © (2004-04-28 15:57) [18]
> WebErr © (28.04.04 15:51) [16]
Т.е. если в вызывающей проге, то можно выделить память как заблагорассудится, а вот отдавая функцию в Access нужно учитывать, что API функции с выделением памяти из "кучи" работают в любой программе, значит наиболее пригодны к применению.
← →
WebErr © (2004-04-28 16:02) [19]Сейчас залазил в help Win32SDK и не нашёл API функций Malloc и Free - теперь они инкапсулированы в интерфейс IMalloc и называются Alloc, Realloc и Free. Извените за дизинформацию - я читаю слишком старые книжки. 8)
← →
Digitman © (2004-04-28 16:10) [20]
> Stas © (28.04.04 15:52) [17]
>
> Ты мне советуешь из Access передать длинну строковой переменной,
> которая Access"у неизвестна ?
а как ты хотел иначе ? иначе не выйдет !
пусть Access распределит строку а-ля
dim Result as String
String = " " (к примеру, 4 пробела)
пусть Access передаст ссылку на буфер строки 2-м ByVal-параметром в твою ф-цию
если 4-х байт достаточно, твоя ф-ция заполняет буфер строки результ.данными и результатом типа Integer показывает реальный размер записанных в строку данных <=4, в противном случае ничего не делает, а возвращает Integer-значение >4 (т.е. реально требуемый размер результ.строки) ... тогда Access может и должен перераспределить строку с требуемой длиной и повторно вызвать твою ф-цию
← →
WebErr © (2004-04-28 16:16) [21]
> Digitman © (28.04.04 16:10) [20]
Ещё нужно учитывать, что Access PChar воспримет как Null-Tetminated string, т.е. нужно выделить под строку на байт больше для завершающего 0-го символа.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.033 c