powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / OCI (extproc) и кодировка
5 сообщений из 5, страница 1 из 1
OCI (extproc) и кодировка
    #39600864
Фотография vava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день. Вопрос, конечно, по с++, но на том форуме наверное спрашивать не стоит.
Пожалуйста, помогите извлечь и раскодировать строку из передаваемого в DLL массива строк.
База на виндавсах, DLL пишу в visual studio 2008.
При конфигурации windows / 12.2EE64 / CL8MSWIN1251 - проблем нет (VS проект в ascii),
а при переходе на AL32UTF8 - нераспознаваемые строки в коллекциях (VS проект в юникоде).
Проблема возникает с параметром типа OCIColl*, когда это [table of varchar2].
Передаваемые одиночные параметры-строки расковыриваются нормально (через CA2W/MultiByteToWideChar), а вот извлеченный из коллекции элемент никак не поддается. Вернее, английские символы распаковываются, а русские - нет (все - код 65533).
Помогите советом или кусочком кода :)
...
Рейтинг: 0 / 0
OCI (extproc) и кодировка
    #39601922
Фотография vava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напишу подробнее, как делал.
Передаваемый объект на стороне БД:
Код: plsql
1.
create or replace type str_arr as table of varchar2(255)



Оформление вызова на стороне БД:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
  function Test_arr(a_in in str_arr,s_in in varchar2) return PLS_INTEGER as
  language C
	library my_lib
	name "Test_arr"
  with context parameters 
  (CONTEXT,
     a_in  OCIColl, a_in  INDICATOR short,
     s_in  string , s_in  INDICATOR short, return int);



Вызов на стороне БД:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function test return number is 
ret number;
ar1_in str_arr:=str_arr();
str_in  varchar2(255):='ФF0';
begin
ar1_in.extend(3);
ar1_in(1):='ФF1';
ar1_in(2):='ФF2';
ar1_in(3):='ФF3';
ret:=Test_arr(ar1_in,str_in);
return ret;
end test;



В Visual Studio проект в юникоде, 64 бит.
Код DLL:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
extern "C" __declspec(dllexport) int Test_arr
(
 OCIExtProcContext * ctx,

 OCIColl *       a_in,
 short         a_in_i,

 OCIString* s_in 
 short*    s_in_i
 )
{
  
  /*работаем со скалярным параметром s_in*/

  CString s=(wchar_t*)s_in;
  CA2W sw((LPCSTR)s.GetBuffer(), CP_UTF8); // sw = "ФF0", всё нормально
  
  /*работаем с параметром-массивом a_in*/
  /*напомню, массив состоит из "ФF1" "ФF2" "ФF3", индексы 0,1,2 */

  OCI_func OF(ctx); // класс для рутинных операций инициализации контекста
  OCIString** ocistring;
  boolean exists;
  text* txt;

  //получаем указатель на 2й элемент массива
  OCICollGetElem(OF.m_myCtx->envhp,OF.m_myCtx->errhp,a_in,1/*номер элемента*/,&exists,(dvoid**)&ocistring,0); 

  txt=OCIStringPtr(OF.m_myCtx->envhp,*ocistring); // txt="?F2", "?" перевёрнут, с кодом 191
  
  CA2W sa((LPCSTR)txt, CP_UTF8); // sa="<>F0", ромбик "<>" с кодом 65533 - нераспознанный символ
  
  return 0;
}



Всяческие
Код: plaintext
1.
2.
USES_CONVERSION;
setlocale(LC_ALL,"Russian");


никак не влияют.

Если БД в кодировке CL8MSWIN1251 - всё работает. Не работает при AL32UTF8.
Игры со всякими NVARCHAR2 ничего не дали.
Может кто сталкивался с передачей объектов через extproc, помогите.
...
Рейтинг: 0 / 0
OCI (extproc) и кодировка
    #39604230
Фотография vava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал передавать через другой тип - OCIArray:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
extern "C" __declspec(dllexport) int Test_arr
(
...
// OCIColl *       a_in,
 OCIArray *    a_in,
 short         a_in_i,
...
 )
{
...


- всё аналогично.

Пробовал выбирать элементы через итератор (вместо OCICollGetElem):
Код: plaintext
1.
2.
3.
4.
status = OCIIterCreate(m_myCtx->envhp, m_myCtx->errhp, a_in, &iterator);
status = OCIIterNext(m_myCtx->envhp, m_myCtx->errhp, iterator, &elem,(dvoid **) &elemind, &eoc);
my_ocistring_elem = *((OCIString **)elem);
txt = OCIStringPtr(m_myCtx->envhp, my_ocistring_elem);


- ничего не меняется, любой национальный символ меняется на CHR(191).

Т.е. проблема где-то в глубине коллекции. Может, нужно как-то конфигурировать OCI для юникода?
...
Рейтинг: 0 / 0
OCI (extproc) и кодировка
    #39604242
...
Рейтинг: 0 / 0
OCI (extproc) и кодировка
    #39604285
Фотография vava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо! Близко, но ситуация наоборот. ENVS в настройках extproc сейчас посмотрю.

Ещё попробовал прямое копирование:
Код: plaintext
1.
OCICollAssign(m_myCtx->envhp,m_myCtx->errhp,a_in,a_out);


и на стороне БД (уже в хранимке) увидел что в получаемом массиве аналогичная ситуация - CHR(191).

А может быть причина в версии ОС - Windows 10 Home, один язык ?
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / OCI (extproc) и кодировка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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