Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.16;
Скачать: CL | DM;

Вниз

тип 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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.024 c
1-1083068196
P_Aleks
2004-04-27 16:16
2004.05.16
Потоки и формы


7-1081422156
race1
2004-04-08 15:02
2004.05.16
add printer


14-1082971693
savva
2004-04-26 13:28
2004.05.16
учитесь:))


14-1083058506
infom
2004-04-27 13:35
2004.05.16
Извините проблема с HTML


14-1082623327
Frozzen
2004-04-22 12:42
2004.05.16
Объявление функции