Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите передать Ansi строчку из UDF / 25 сообщений из 52, страница 1 из 3
31.08.2016, 15:28
    #39301213
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Добрый день.

Делал по аналогии, как где нашел.
Код: sql
1.
2.
3.
4.
5.
6.
function INIReadString(AStrSection, AStrParam, AINIData: PAnsiChar; DefaultParam: PAnsiChar): PAnsiChar; cdecl; export;
begin
  Result := PAnsiChar(AnsiString(MainUnit.MyINIReadString(UTF8ToString(AStrSection), UTF8ToString(AStrParam), UTF8ToString(AINIData), UTF8ToString(DefaultParam))));
end;

MainUnit.MyINIReadString возвращает String



Код: sql
1.
2.
3.
4.
5.
6.
7.
DECLARE EXTERNAL FUNCTION INIREADSTRING
    CSTRING(20) CHARACTER SET UTF8,
    CSTRING(20) CHARACTER SET UTF8,
    CSTRING(1024) CHARACTER SET UTF8,
    CSTRING(512) CHARACTER SET UTF8
RETURNS CSTRING(512)
ENTRY_POINT 'INIReadString' MODULE_NAME 'levdis.dll';



Строчки, в которых цифры и англ. буквы - возвращаются запросом, если в строке русские буквы - malformed string.

Подскажите, пожалуйста, что исправить?
...
Рейтинг: 0 / 0
31.08.2016, 15:33
    #39301218
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Hello, Devillio!
You wrote on 31 августа 2016 г. 15:32:03:

Devillio> MainUnit.MyINIReadString возвращает String
в сильно разных дельфях этот самый "стринг" сильно разный.
иди к дельфятникам.

зы: тут Delphi никто не знает.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
31.08.2016, 15:39
    #39301228
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Delphi XE2.
А тему пересоздать или переместят? :)
...
Рейтинг: 0 / 0
31.08.2016, 15:46
    #39301234
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Devillioчто исправить?
Практически всё. Начиная с работы с памятью и кончая преобразованием к utf-8.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
31.08.2016, 15:59
    #39301245
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
DevillioПодскажите, пожалуйста, что исправить?
16518686 пример в floattochar, и не забывай про free_it.
...
Рейтинг: 0 / 0
31.08.2016, 16:01
    #39301249
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Dimitry Sibiryakov, спасибо! без преобразований, вот так заработало )))

procedure INIReadString(AStrSection, AStrParam, AINIData: PAnsiChar; DefaultParam: PAnsiChar); cdecl; export;
begin
StrPCopy(DefaultParam,
AnsiString(MainUnit.MyINIReadString(AStrSection, AStrParam, AINIData, DefaultParam)));
end;

DECLARE EXTERNAL FUNCTION INIREADSTRING
CSTRING(128),
CSTRING(128),
CSTRING(1024),
CSTRING(512)
RETURNS PARAMETER 4
ENTRY_POINT 'INIReadString' MODULE_NAME 'levdis.dll';

подскажите, так "с памятью" нормально или что-то еще надо?
...
Рейтинг: 0 / 0
31.08.2016, 16:09
    #39301256
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Devillio,

http://www.ibase.ru/unicode_faq/
в самом конце, последний пункт про udf.

Но тут не надо забывать, что в udf передаются строки в чарсете данных или чарсете коннекта. Если ты явно не объявляешь чарсет параметров udf, то чарсет будет как "по умолчанию у БД". И если у базы win1251, то параметры будут win1251, и соответственно, возникнет преобразование из чарсета коннекта в чарсет параметра udf.

А если параметры явно в utf8 объявлены, то тогда внутри udf преобразование бессмыслено. В последнем твоем варианте MyINIReadString должно понимать параметры в utf8.
...
Рейтинг: 0 / 0
31.08.2016, 16:15
    #39301261
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Devillioтак "с памятью" нормально или что-то еще надо?

С памятью так нормально, но с остальным, как уже сказали, работает до первого дятла.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
31.08.2016, 16:23
    #39301270
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Dimitry Sibiryakov,

в моем примере может быть не совсем понятно, с какого рожна входные строки PAnsiString. Хотя первое же преобразование типа (UTF8String(p1)) как бы намекает, что к чему. Впрочем, надо будет наваять вообще чистую utf8 udf... Хотя вроде там и ваять-то нечего. объявляем параметры с чарсетом utf8, получаем utf8string, возвращаем utf8string. По идее, так и должно быть. Но надо проверить...
...
Рейтинг: 0 / 0
31.08.2016, 16:29
    #39301278
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Hello, Kdv!
You wrote on 31 августа 2016 г. 16:27:37:

Kdv> надо проверить...в статье добавь указание версии делфи.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
31.08.2016, 16:34
    #39301289
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
kdv,

А позвольте глупый вопрос?

А если БД создавать с UTF8 кодировкой - она будет универсальной для всех языков?
Просто сейчас попробовал - создал с charset UDF8, соединяюсь с таким же, вроде бы русский язык работает, эта функция UDF - тоже.
Где здесь грабли будут?
...
Рейтинг: 0 / 0
31.08.2016, 16:44
    #39301303
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
DevillioА если БД создавать с UTF8 кодировкой - она будет универсальной для всех языков?
кодировка у базы - это не кодировка базы, а ШАБЛОН чарсета, который будет использоваться для строковых (и текстовых блобов) типов данных при создании объектов - таблиц, процедур, функций, view, если у них чарсет явно не указан .

Например. Создаем базу "в win1251". Пишем
create table a (name varchar(30);
столбец name будет иметь чарсет win1251.

пишем в этой же базе
create table a (name varchar(30) character set utf8;

столбец name будет иметь чарсет utf8.

И т.д. Собственно, у базы указывается DEFAULT character set, а не просто character set. Так что, у одной таблицы разные столбцы могут иметь разные чарсеты, отличные от default, если их указать явно.
А вот дальше уже будет работать преобразование "чарсет коннекта" -> "чарсет столбца/параметра".
...
Рейтинг: 0 / 0
31.08.2016, 16:47
    #39301307
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Огромная благодарность за разъяснения!
...
Рейтинг: 0 / 0
31.08.2016, 16:52
    #39301314
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
DevillioОгромная благодарность за разъяснения!
Я-ж говорю, сайт ibase нафиг не нужен.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
29.03.2018, 13:13
    #39622637
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
....и выкопаю стюардессу!

Как на интерпретацию CSTRING и особенно его "размера" в скобках влияют:
1) connection charset ?
2) database default charset ?

Я к тому, что вот тут - http://freeadhocudf.org/documentation_english/dok_eng_blob.html - у функций идут параметры CSTRING(32760) - причем и в UTF-8 версиях и в неюникодных, один чёрт.

А вот тут на FB 2.5.5 пытаются объявить CSTRING(32660) - и выпадают на implementation limit exceeded
https://stackoverflow.com/questions/49547235/firebird-errors-when-using-symmetricds
...
Рейтинг: 0 / 0
29.03.2018, 13:15
    #39622640
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
....и ещё раз выкопаю.

Посмотрел лангреф и девгайд IB6, лангрефы FB2.5 (Eng&Rus) - везде говорится, что предел размера CSTRING указан в байтах, а не в буквах. Про кодировку же самих букв не говорится вообще ни в одной доке...
...
Рейтинг: 0 / 0
29.03.2018, 13:25
    #39622647
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Так же как и у любого другого поля/параметра чарсет параметров UDF наследуется от
умолчательного чарсета БД если не указан явно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
29.03.2018, 14:01
    #39622678
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Dimitry SibiryakovТак же как и у любого другого поля/параметра

здесь ты неявно отсылаешь "к любому другому" SQL-типу данных

но CSTRING - он если смотреть синтаксические диаграммы в доках вовсе не стандартный тип данных, а особый исключительный случай, а для него кодировки не прописаны

https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-ddl-extfunc.html

а предел длины и вовсе явно прописан в байтах, а не буквах....

--------

хотя смотрю я в ib_udf2.sql и вижу там DECLARE EXTERNAL FUNCTION strlen STRING(32767) CHARACTER SET NONE

то есть, можно, нло в документации пропустили

а вот для сравнения в ib_udf.sql кодировки нет - DECLARE EXTERNAL FUNCTION strlen СSTRING(32767) RETURNS ....

в fbudf.sql нету вообще CSTRING
...
Рейтинг: 0 / 0
29.03.2018, 16:18
    #39622747
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
AriochКак на интерпретацию CSTRING и особенно его "размера" в скобках влияют:
1) connection charset ?
2) database default charset ?
на втором вопросе я скоро язву заработаю - дефолтный чарсет базы, это чарсет, который используется для строковых столбцов или переменных, если у них никакой чарсет не указан. При создании метаданных - таблиц, процедур, триггеров.
Больше "дефолтный чарсет" ни для чего не используется. Так что, если метаданные УЖЕ существуют, про дефолтный чарсет можно забыть.

Чарсет коннекта - определяет перекодирование или его отсутствие, если чарсет данных не совпадает с чарсетом коннекта.

При чем тут "размер cstring в скобках"??? Он если и относится, то ко второму вопросу. И то, если чарсет не указан явно.

авторпредел размера CSTRING указан в байтах, а не в буквах. Про кодировку же самих букв не говорится вообще ни в одной доке...
не надо ля-ля, про "не говорится". Написано в руководстве по языку, например по ФБ 2.5 - страница 34.
" для более экзотических алфавитов, рекомендуется работать с набором символов UTF8. При этом следует иметь в виду, что на один символ в данном наборе приходится до 4 байт. Следовательно, максимальный размер символов в символьных полях
составит 32676/4 (8192) байта на символ. При этом следует обратить внимание, что фактически значение параметра «байт на символ» зависит от диапазона, к которому принадлежит символ: английские буквы занимают 1 байт, русские буквы кодировки WIN1251 — 2 байта, остальные символы — могут занимать до 4-х байт.
"

А насчет CSTRING - все те же правила по длине и кодировкам, что и для CHAR/VARCHAR. CSTRING просто 0-терминируемая строка, специфическая для udf.

Ты, собственно, чего хочешь - чтобы в документации дописали пару предложений? Или чтобы ... что?
...
Рейтинг: 0 / 0
29.03.2018, 17:49
    #39622834
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
kdv,

Чтобы выяснили как реально обстоят дела и чётко отразили в обеих документациях, ENG/RUS

> например по ФБ 2.5 - страница 34.

Открываю официальный сайт, https://www.firebirdsql.org/en/reference-manuals/
Открываю официальное руководство Firebird 2.5 Language Reference (Russian)
"6 сентября 2015 — v.0336-1 для Firebird 2.5.4", страница 34, "Подтипы BLOB" и "Особенности BLOB"

BLOB <> CSTRING

Делаю полнотекстовый поиск, твой кусок нахожу на страницах 29/30

Символьные типы данных
В СУБД Firebird для работы с символьными данными есть тип данных фиксированной
длины CHAR и строковый тип данных VARCHAR переменной длины.

{VAR}CHAR <> CSTRING

> Так что, если метаданные УЖЕ существуют
....и у эти метаданных есть чарсет - то да. А если нет? По документации у CSTRING никакого чарсета нет!

> Чарсет коннекта - определяет перекодирование или его отсутствие

А если у БД нет своего коннекта, например NONE ?
А если коннект используется для создания БД на сервере, а не к уже существующей БД.

Исходная ситуация: есть БД, она пересоздается и переливаются данные, в процессе этого вылезает превышение implementation limit, которого 1) на исходной БД нет; 2) не должно быть по докам; 3) не должно быть по прецеденту fbUDF (тот еще прецедентик, но какой есть, ПОСЛЕ облома с документацией).

Понимаешь, в тот момент когда сервер ведёт себя не по документации - под сомнение ставится всё. Причина ошибки ищется в любом возможном месте. Потому что, если ошибка возникает в "правильном" и очевидном месте - он решается не приходя в сознание и на форумы никто не лезет.
...
Рейтинг: 0 / 0
29.03.2018, 18:07
    #39622850
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Arioch,

потому что CSTRING это не тип данных Firebird и за пределами DECLARE EXTERNAL FUNCTION не используется. При возврате из функции он скорее всего приводится к CHAR или VARCHAR (точно не скажу). Возможно проблема в этом самом приведении. У меня тоже нет сведений как это работает.

CSTRING(<size>) прямо отображается на AnsiChar[<size>] поэтому непосредственного чарсета у этого "типа" быть не может
...
Рейтинг: 0 / 0
29.03.2018, 18:30
    #39622857
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Симонов ДенисПри возврате из функции он скорее всего приводится к CHAR или VARCHAR (точно не скажу). Возможно проблема в этом самом приведении. У меня тоже нет сведений как это работает.
Лично я не осилил, что ты пытался сказать. Приведение делается к
типу объекта "присвоения" - т.е. "переменная слева", cast, поле и пр.
Включая чарсет, разумеется, если они разные.
...
Рейтинг: 0 / 0
29.03.2018, 18:30
    #39622858
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Симонов ДенисCSTRING(<size>) прямо отображается на AnsiChar[<size>]
поэтому непосредственного чарсета у этого "типа" быть не можетЭто чушь, ИМХО.
...
Рейтинг: 0 / 0
29.03.2018, 20:05
    #39622894
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Гаджимурадов Рустам,

почему же чушь. Как оно будет внутри UDF выглядить?
...
Рейтинг: 0 / 0
29.03.2018, 20:49
    #39622913
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите передать Ansi строчку из UDF
Симонов Денис> Как оно будет внутри UDF выглядить?

Не понял вопроса. Внутри UDF будет выглядеть как-то
(как запрограммируют), в каком-то чарсете. Снаружи -
как будет нужно снаружи, т.е. в т.ч. вдруг чарсете.

Тут UDF, в т.ч. CSTRING, от любых других строк и
литералов ничем не отличается - чарсеты приводятся
совершенно прозрачно и автоматически.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите передать Ansi строчку из UDF / 25 сообщений из 52, страница 1 из 3
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]