Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.032 c
3-1082376634
}|{yk
2004-04-19 16:10
2004.05.16
Cannot transliterate


1-1083345148
Learner
2004-04-30 21:12
2004.05.16
Корректное уничтожение формы.


6-1080481375
Diz
2004-03-28 17:42
2004.05.16
Проблемы с POP3


4-1080740994
Lobster
2004-03-31 17:49
2004.05.16
Как добавить русский язык в Windows?


8-1075045587
Driverrr
2004-01-25 18:46
2004.05.16
Детектор движения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский