crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Передача массива из Qt программы в Free Pascal библиотеку, Вылетает SIGFPE
rominf
  опции профиля:
сообщение 21.8.2012, 23:10
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 20.8.2011
Пользователь №: 2820

Спасибо сказали: 1 раз(а)




Репутация:   0  


Здравствуйте!

К программе на Qt 4 подключается .so библиотека, написанная на Free Pascal (Lazarus). В библиотеке есть функция, принимающая по указателю массив (Size = 10):
type
  TDoubleArray = array  [0..Size - 1] of Double;
  PDoubleArray = ^TDoubleArray;    

procedure Sort(A: PDoubleArray); stdcall;


В программе:
std::vector<double> v(Size, 0);
// Заполнение вектора
typedef double (*Sort)(double [Size]);
Sort sort = (Sort)lib->resolve("Sort");
if (sort)
{
    sort(&v[0]);
    QString s = QString::number(-1.1); // Аналогично если на этом месте стоит что-нибудь с динамическим созданием объекта ("new") (*)
    ...
}

На (*) вылетает с ошибкой SIGFPE.
Если заменить на передачу по ссылке (procedure Sort(var A: TDoubleArray); stdcall;) то всё идентично.
Когда делал аналогично для сумы, но с передачей по значению (function Sum(A: TDoubleArray): Double; stdcall;), то ошибки не возникало.
Замечу, что судя по тому, что показывает дебагер, обе функции работают (при возврате управления в программу вижу отсортированный массив).
Чувствую, что проблема в выделении памяти, но, к сожалению, раньше не имел опыта по созданию динамических библиотек, поэтому не понимаю, что у меня неправильно. И мне не очень нравится использование вектора, чтобы передать его как массив, но писать в стиле С не удобно.
Подскажите, пожалуйста, в чём проблема. Буду благодарен за ссылки на литературу для глубокого изучения вопроса выделения памяти, стека вызовов, динамических библиотек.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.8.2012, 13:35
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Раскрывающийся текст
а что там с сортировкой намучено ?

можно попроще

#include <algorithm>

std::vector<double> v(Size, 0)
....
....
std::sort(v.begin(),v.end());


насчёт твоего вызова sort(&v[0]); . Где этой функции указана длина массива ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
rominf
  опции профиля:
сообщение 22.8.2012, 20:37
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 20.8.2011
Пользователь №: 2820

Спасибо сказали: 1 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 22.8.2012, 14:35) *
Раскрывающийся текст
а что там с сортировкой намучено ?

можно попроще

#include <algorithm>

std::vector<double> v(Size, 0)
....
....
std::sort(v.begin(),v.end());

насчёт твоего вызова sort(&v[0]); . Где этой функции указана длина массива ?



Конечно, я знаю, что есть stl :) Я немного упростил код, чтобы выделить основную мысль. Надо было об этом написать, чтобы не было недоразумений.

Где указана длина? При вызове я передаю только указатель, получается нигде. С другой стороны, в typedef-e я указываю размер массива [typedef double (*Sort)(double [Size]);], может там есть какая-то магия?).
Честно говоря, сам был очень удивлён, но:
  1. При нажатии "шаг внутрь" (F11) на шаге вызова функции дебагер начинает отлаживать библиотеку (показывает исходники на Free Pascal) с возможностью пошаговой отладки, breakpoint-ами, просмотром переменных. Честно говоря не ожидал, что это всё будет работать, тем более в .so, тем более на другом языке.
  2. Когда я смотрю на массив внутри библиотеки то он абсолютно корректный. Причём во всех 3 случаях: по значению, по ссылке, через указатель.
Логически я понимаю, что надо бы передать длину в библиотеку, только как потом ею воспользоваться из Pascal не используя Copy и Move (от чего пропадает смысл от использования передачи по ссылке или указателю) я не знаю. Можно конечно туда-обратно копировать, но это плохо, т.к. массив немаленький, да и вызываться эта функция будет около раза в секунду.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 23.8.2012, 9:02
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Посмотри, что значит SIGFPE вики.

И раз уж ты можешь шагнуть в sort, так в чем проблема?
Посмотри где падает и какие значения переменных при падении, ну впрочем че учить, если умеешь пользоваться отладчиком))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
rominf
  опции профиля:
сообщение 23.8.2012, 11:42
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 20.8.2011
Пользователь №: 2820

Спасибо сказали: 1 раз(а)




Репутация:   0  


Цитата(PAFOS @ 23.8.2012, 10:02) *
Посмотри, что значит SIGFPE вики.


Спасибо за ссылку.


Я не могу понять, почему возникает именно эта ошибка: "попытка выполнения ошибочной арифметической операции". Я же выделяю память, скорее SIGSEGV должно вылететь, если я что-то криво делаю.

Цитата(PAFOS @ 23.8.2012, 10:02) *
И раз уж ты можешь шагнуть в sort, так в чем проблема?
Посмотри где падает и какие значения переменных при падении, ну впрочем че учить, если умеешь пользоваться отладчиком))

Оно падает у меня прямо на следующей строке после вызова функции из библиотеки. Ничего кроме объекта главного окна (с несколькими виджетами на нём), массива, указателя на QLibrary и функцию из библиотеки у меня нет. Массив правильной длины с такими же числами, как на входе, отсортирован. Что ещё можно посмотреть?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 23.8.2012, 16:22
Сообщение #6


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


хм....

procedure Sort(A: PDoubleArray); stdcall;
- говорит что у тя процедура, т.е. она в понимании С/С++ возвращает void.
typedef double (*Sort)(double [Size]);
- говорит, что у тебя фунция, которая должна возвращать тип double

подозреваю, что из-за этого у тебя портится стек и каша получается...
попробуй
typedef void (*Sort)(double [Size]);

вместо
typedef double (*Sort)(double [Size]);


==========================
чет тупанул )

typedef double (*Sort)(double [Size]);


это че, получается double теперь у тебя есть указатель на функцию?

Сообщение отредактировал PAFOS - 23.8.2012, 16:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 23.8.2012, 16:29
Сообщение #7


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


я не спец в паскале, но, похоже, что у тебя в Си описана функция Sort, которая возвращает значение double. а в паскале описана процедура - то есть, результата у неё вообще нет. если я правильно помню, в паскале с возвратом значения - это функции. возможно, из-за этого при выходе рушится стек.
ещё нужно проверить, что stdcall также указан и в сишном коде.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 23.8.2012, 16:31
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Iron Bug, во во)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
rominf
  опции профиля:
сообщение 23.8.2012, 17:49
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 20
Регистрация: 20.8.2011
Пользователь №: 2820

Спасибо сказали: 1 раз(а)




Репутация:   0  


Цитата(PAFOS @ 23.8.2012, 17:22) *
хм....

procedure Sort(A: PDoubleArray); stdcall; - говорит что у тя процедура, т.е. она в понимании С/С++ возвращает void.
typedef double (*Sort)(double [Size]); - говорит, что у тебя фунция, которая должна возвращать тип double

подозреваю, что из-за этого у тебя портится стек и каша получается...
попробуй
typedef void (*Sort)(double [Size]);
вместо
typedef double (*Sort)(double [Size]);

==========================
чет тупанул )

typedef double (*Sort)(double [Size]);

это че, получается double теперь у тебя есть указатель на функцию?

PAFOS, Iron Bug, большое спасибо!
Мне ужасно стыдно. :blush: Действительно, вся проблема именно в этом (а ларчик просто открывался). Видимо когда экспериментировал туда-сюда менял, а это забыл переделать. Да и в typedef-ах путаюсь, мало опыта ещё.


Извините, пожалуйста, что потратил ваше время на вникание в мою "проблему", возникшую из-за тупейшей ошибки.

Тема закрыта (кстати, плашку [SOLVED] как-нибудь можно повесить?)






Цитата(Iron Bug @ 23.8.2012, 17:29) *
я не спец в паскале, но, похоже, что у тебя в Си описана функция Sort, которая возвращает значение double. а в паскале описана процедура - то есть, результата у неё вообще нет. если я правильно помню, в паскале с возвратом значения - это функции. возможно, из-за этого при выходе рушится стек.
ещё нужно проверить, что stdcall также указан и в сишном коде.

Ответил Вам и PAFOS одновременно на сообщение выше.

Цитата(Iron Bug @ 23.8.2012, 17:29) *
я не спец в паскале, но, похоже, что у тебя в Си описана функция Sort, которая возвращает значение double. а в паскале описана процедура - то есть, результата у неё вообще нет. если я правильно помню, в паскале с возвратом значения - это функции. возможно, из-за этого при выходе рушится стек.
ещё нужно проверить, что stdcall также указан и в сишном коде.


Ответил Вам и PAFOS сообщение выше.

Извините!) Не разобрался, как работает форум. Раньше не пользовался древовидными форумами.

Как-нибудь можно отредактировать/удалить сообщения?


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 23.8.2012, 19:01
Сообщение #10


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Отредактировать сообщение можно будет после 20 оставленных постов )
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 1.12.2024, 23:44