URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7893
[ Назад ]

Исходное сообщение
"Обмен данными с shared object"

Отправлено blackswan , 10-Фев-09 10:23 
Имеется собраная мною shared object, необходимо не только передавать туда параметры-значения, но и несколько параметров-ссылок, чтоб возвращался результат работы библиотеки в некоторых переменных обратно, но пока что не вижу возврата результата, не знаю, как объявить правильнее. Пробовал также использовать & -взятие адреса, но пока не получается. Может это как-то связано с областью видимости переменных? Ключи компилятора для библиотеки: -ftls-model=local-dynamic и -fpic (GCC).


объявление функции в библиотеке:

void mainprocfunc(char *sPictureSourcePath, char *nProcessingFunction,char *sPicInputFormat,char *sPicOutputFormat,
char *sFormatParams,char *sProcessingParams,int iErrorCode, char *sPictureDest,float rProcTime);


три последних параметра должны передаваться по ссылке при вызове.
код вызова в вызывающей программе:

void *lib_library;
void (*mainprocfunc)(char *,char *,char *,char *,char *,char *,int, char *, float );
char *PicPath1,*nProcP,*InForm,*OutForm,*ForPars,*ProcPars,*PicPath2;
int Errcd;
float prctime;
.......................
lib_library = dlopen("lib.so",RTLD_NOW|RTLD_GLOBAL);
mainprocfunc = dlsym(lib_library, "mainprocfunc");
(mainprocfunc)(PicPath1,nProcP,InForm,OutForm,ForPars,ProcPars,Errcd,PicPath2,pr
ctime);


Содержание

Сообщения в этом обсуждении
"Обмен данными с shared object"
Отправлено NuINu , 10-Фев-09 10:37 
>три последних параметра должны передаваться по ссылке при вызове.

объявляете так:
void mainprocfunc(char *sPictureSourcePath, char *nProcessingFunction,char *sPicInputFormat,char *sPicOutputFormat,
char *sFormatParams,char *sProcessingParams,int* iErrorCode, char* *sPictureDest,float* rProcTime);

работайте так:
*iErrorCode = 23;

>код вызова в вызывающей программе:

(mainprocfunc)(PicPath1,nProcP,InForm,OutForm,ForPars,ProcPars,&Errcd,&PicPath2,&pr
ctime);

никаких отличий в работе с so по сравнени со статической линковкой быть не должно


"Обмен данными с shared object (php-расширение)"
Отправлено blackswan , 10-Фев-09 14:07 
>[оверквотинг удален]
>объявляете так:
>void mainprocfunc(char *sPictureSourcePath, char *nProcessingFunction,char *sPicInputFormat,char *sPicOutputFormat,
>char *sFormatParams,char *sProcessingParams,int* iErrorCode, char* *sPictureDest,float* rProcTime);
>работайте так:
>*iErrorCode = 23;
>>код вызова в вызывающей программе:
>(mainprocfunc)(PicPath1,nProcP,InForm,OutForm,ForPars,ProcPars,&Errcd,&PicPath2,&pr
>ctime);
>никаких отличий в работе с so по сравнени со статической линковкой быть
>не должно

спасибо, помогло. теперь другая проблема. библиотека вызывается из php-расширения, тоже сделанного в виде shared object. При возврате строки char * из фукнции возникает ошибка Segmentation fault: 11 (core dumped) . Как я понял, полученная строка не может правильно перейти в таблицу переменных php. Ниже привожу код, строка с ***** и есть проблемной, из-за неё выпадает ошибка. Функция fprintf для проверки выдает нормальную строку, отрабатывает без ошибок.

char *path_to_file;
int error_of_processing,pic_path_len;
float time_of_processing;
zval *err_code,*pic_dest,*time_proc;
MAKE_STD_ZVAL(err_code);
MAKE_STD_ZVAL(pic_dest);
MAKE_STD_ZVAL(time_proc);
..........................
(mainprocfunc)(spicpath,sprocessfunc,spicinformat,spicoutformat,sformatpar,sprocpar,&error_of_processing,&path_to_file,&time_of_processing);
pic_path_len = strlen(path_to_file);
fprintf(filehelp,"StringPath size: %d StringPath %s \n",pic_path_len,path_to_file);
.............................
    ZVAL_LONG(err_code,error_of_processing);
    ZVAL_DOUBLE(time_proc,time_of_processing);
//    pic_dest->type = IS_STRING;
//    pic_dest->value.str.len = pic_path_len;
//    pic_dest->value.str.val = estrdup(path_to_file);

*****    ZVAL_STRINGL(pic_dest,path_to_file,pic_path_len,1);


"Обмен данными с shared object (php-расширение)"
Отправлено NuINu , 10-Фев-09 14:39 
>[оверквотинг удален]
>pic_path_len = strlen(path_to_file);
>fprintf(filehelp,"StringPath size: %d StringPath %s \n",pic_path_len,path_to_file);
>.............................
> ZVAL_LONG(err_code,error_of_processing);
> ZVAL_DOUBLE(time_proc,time_of_processing);
>//    pic_dest->type = IS_STRING;
>//    pic_dest->value.str.len = pic_path_len;
>//    pic_dest->value.str.val = estrdup(path_to_file);
>
>***** ZVAL_STRINGL(pic_dest,path_to_file,pic_path_len,1);

если ошибки здесь нет, то она возможно где то раньше. а здесь ее (скрее всего) нет
вот и разберитесь где вы получаете память для path_to_file
судя по логике, это должно происходить где то в mainprocfunc(иначе не зачем было передавать туда ее как ссылку)
все ли там происходит правильно.

ну а не поможет исследуте дамп.


"Обмен данными с shared object (php-расширение)"
Отправлено blackswan , 10-Фев-09 15:15 
>если ошибки здесь нет, то она возможно где то раньше. а здесь
>ее (скрее всего) нет
>вот и разберитесь где вы получаете память для path_to_file
>судя по логике, это должно происходить где то в mainprocfunc(иначе не зачем
>было передавать туда ее как ссылку)
>все ли там происходит правильно.
>
>ну а не поможет исследуте дамп.

path_to_file пока что однозначно возвращает строку "./out.jpg" ,для чего и проверяю функцией fprintf(filehelp,"StringPath size: %d StringPath %s \n",pic_path_len,path_to_file), которая выводит всё правильно:
StringPath size: 9 StringPath ./out.jpg

не имею представления, как провести дебаг этого кода, делал всё по примерам создания php-приложений. Чтоб хоть как-то проверить работу функции mainprocfunc, вызываемой из библиотеки, сделал небольшую программу, делающую аналогичный вызов этой функции из подключаемой .so, там строка возвращается без ошибок. Проблема в макросе ZVAL_STRING, который должен установить тип и значение переменной, вместо него уже использовал аналогичный код прямого присваивания значений, но та же ошибка.

P.S. К своему стыду, не знаю, как исследовать дамп.


"Обмен данными с shared object (php-расширение)"
Отправлено NuINu , 10-Фев-09 17:35 
>
>P.S. К своему стыду, не знаю, как исследовать дамп.

пример, компилируем и собираем с опцией -g
программа gen_fail

#Анализ core
#gdb gen_fail core
#(gdb) info stack
##0  0x4007983d in _IO_vfscanf_internal () from /lib/libc.so.6
##1  0x4008465d in vsscanf () from /lib/libc.so.6
##2  0x4007feed in sscanf () from /lib/libc.so.6
##3  0x0804842b in main (argc=3, argv=0xbffff474) at gen_fail.c:16
#(gdb) l *0x0804842b
#0x804842b is in main (gen_fail.c:16).
#11         } else {
#12            /*a = strtof(argv[1], endptr);
#13            endptr = NULL;
#14            b = strtof(argv[2], endptr);*/
#15            sscanf(argv[1],"%f", &a);
#16            sscanf(argv[2],"%f", b); /*segmentatiom fault call ;-))*/
#17            /*sscanf(argv[2],"%f", &b);*/
#18         }
#19
#20         float res;
#(gdb) q


"Обмен данными с shared object (php-расширение)"
Отправлено vic , 10-Фев-09 21:20 
>path_to_file пока что однозначно возвращает строку "./out.jpg" ,для чего и проверяю функцией

как выделяется память под строку path_to_file в вашей функции?
приведите код функции связанный с этой строкой.

>P.S. К своему стыду, не знаю, как исследовать дамп.

шорт-подсказку уже дали, а популярно про отладчик тут:
http://www.opennet.me/docs/RUS/gdb/gdb_toc.html


"Обмен данными с shared object (php-расширение)"
Отправлено dev , 27-Апр-09 07:14 
>При возврате строки char * из фукнции возникает
>ошибка Segmentation fault: 11 (core dumped).

возможно у вас в so есть глобальная переменная-указатель, значение которой присваивает один процесс, а читает другой - в результате segmentation fault


"Обмен данными с shared object"
Отправлено vic , 10-Фев-09 11:38 
>Имеется собраная мною shared object, необходимо не только передавать туда параметры-значения, но
>и несколько параметров-ссылок, чтоб возвращался результат работы библиотеки в некоторых переменных
>обратно, но пока что не вижу возврата результата, не знаю, как
>объявить правильнее. Пробовал также использовать & -взятие адреса, но пока не
>получается. Может это как-то связано с областью видимости переменных? Ключи компилятора
>для библиотеки: -ftls-model=local-dynamic и -fpic (GCC).
>

Вы определитесь как вы будете получать данные из функции, по ссылке или по адресу.
Напишите нужную вам функцию, прямо в свое коде, и работающую функцию просто перенесите в so, и далее ее оттуда экспортируйте.