Russian Qt Forum
Сентябрь 30, 2024, 20:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Qt работа с UDF  (Прочитано 16474 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« : Октябрь 20, 2009, 11:40 »

Вопрос таков, возможно ли на Qt написать udf-ку для firebird Непонимающий

Я пробовал сделать вот так
Код:
extern "C"
{
    char* result(char* );
}

char* result(char* a)
{
    return a;
}

И затем объявление в самом Firebird, так все работает на ура, но если я в Qt подключаю хотя бы
Код:
#include <iostrem>

то во-первых размер длл-ки увеличивается в 10 раз, и сразу же вызов функции из БД невозможен, БД пишет мол нет такой ф-ции. При этом смотрю через TotalCommander в длл-ке кроме моей ф-ции появляются еше какие то сторонние .Может подскажете советом.
Записан
Zmeishe
Гость
« Ответ #1 : Октябрь 20, 2009, 11:53 »

Моя UDF работает без проблем и на Linux и на Win

Вот пример с одной стандартной функцией pow(...) из #include <math.h>
и одной Qt функцией qRound64(...) из #include <QtCore/QtGlobal>


ib_round.cpp
Код:
#include <QtCore/QtGlobal>
#include <math.h>

#ifdef Q_OS_WIN
# if defined( QT_BUILD_MATH_LIB )
# define Q_MATH_EXPORT __declspec(dllexport)
# else
# define Q_MATH_EXPORT __declspec(dllimport)
# endif
#else
# define Q_MATH_EXPORT
#endif  


extern "C" Q_MATH_EXPORT double ib_udf_round_to(double *x, int *y)
{
 double p = pow(10.0, *y);
 return qRound64(*x * p) / p;
}

ib_round.pro
Код:
...
win32 {
 DEFINES +=  QT_BUILD_MATH_LIB
}
...
« Последнее редактирование: Октябрь 20, 2009, 11:57 от Zmeishe » Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #2 : Октябрь 20, 2009, 12:54 »

При работе с числами у меня тоже проблем нету, но мне нужно работать со строками, и если я хоть в одном месте объявляю Qt шную строку
Код:
QString str;

или C++
Код:
#include <string>
std::string str;

то все смерть, функция невидна и т.д и т.п.

Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #3 : Октябрь 20, 2009, 13:17 »

создается такое впечатление как будто ваша DLL с UDF не линкуется со всякими QtCore - попробуйте использовать свою DLL-UDF другой тестовой программой, которая попытается вызвать эту же ф-ю.
Записан
Zmeishe
Гость
« Ответ #4 : Октябрь 20, 2009, 13:56 »

При работе с числами у меня тоже проблем нету...
А при работе с числами ты какие Qt-шные функции используешь?
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #5 : Октябрь 20, 2009, 14:29 »

создается такое впечатление как будто ваша DLL с UDF не линкуется со всякими QtCore - попробуйте использовать свою DLL-UDF другой тестовой программой, которая попытается вызвать эту же ф-ю.

пробовал написать просто тестовую софтину, тоже ку-те-шную которая вызавыет ф-ции, все нормально отрабатывает.

Цитировать
А при работе с числами ты какие Qt-шные функции используешь?

Ну на самом, деле при работе с числами именно ку-тешные ф-ции не юзаю, ибо чистого C++ хватает, а тут строку нужно закодировать и самое простое на мой взгляд это

Код:
QByteArray::toString()

И стало быть QString тоже нужно использовать, но вот как только так сразу и не работает Злой

Свою реализацию base64 писать не хочется нашел на C++ там используется std::string , но вот как только его использовать  то сразу вход в функцию из Firebird не найден, а если свою софтину написать то все отлично работает.
Записан
Zmeishe
Гость
« Ответ #6 : Октябрь 20, 2009, 14:43 »

Цитировать
А при работе с числами ты какие Qt-шные функции используешь?

Ну на самом, деле при работе с числами именно ку-тешные ф-ции не юзаю, ибо чистого C++ хватает, а тут строку нужно закодировать и самое простое на мой взгляд это
Сделай UDF, как у меня, с числами и с qRound() / qRound64()
И скажи - работает или нет.
Если не работает, то процесс interbase / firebird не видит Qt*.dll
Для Win пропиши переменную PATH
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #7 : Октябрь 20, 2009, 14:47 »

Переменная прописана, и твой пример работает отлично, но со строками проблема дай путь...
Записан
Zmeishe
Гость
« Ответ #8 : Октябрь 20, 2009, 14:56 »

Ну прям, не знаю.

Есть у меня ещё вот такая - и тоже работает не один год
Код:
extern "C"  __declspec(dllexport) char* ib_udf_createUUID()
{
  char *p;
 
  p = QUuid::createUuid().toString().toLatin1().data();
  return p;
}

Заметь - toString() нормально юзается.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #9 : Октябрь 20, 2009, 15:22 »

Вот все и не работает.

в общем делаю вот так

Qt код
Код:
#include <QtCore/QtGlobal>
#include <QUuid>

#ifdef Q_OS_WIN
# if defined( QT_BUILD_MATH_LIB )
# define Q_MATH_EXPORT __declspec(dllexport)
# else
# define Q_MATH_EXPORT __declspec(dllimport)
# endif
#else
# define Q_MATH_EXPORT
#endif

extern "C"  __declspec(dllexport) char* ib_udf_createUUID()
{
  char *p;

  p = QUuid::createUuid().toString().toLatin1().data();
  return p;
}

декларация в Firebird
Код:
DECLARE EXTERNAL FUNCTION UDF
RETURNS CSTRING(254) FREE_IT
ENTRY_POINT 'ib_udf_createUUID' MODULE_NAME 'crqphudf';

длл-ка лежит где нужно, при вызове
Код:
select UDF() from Object

говорит что точка входа в длл не найдена, может ешё что то нужно?
Записан
BRE
Гость
« Ответ #10 : Октябрь 20, 2009, 15:27 »

Код:
extern "C"  __declspec(dllexport) char* ib_udf_createUUID()
{
  char *p;
 
  p = QUuid::createUuid().toString().toLatin1().data();
  return p;
}
Нормально работает не один год....
Поищи по форуму темы про подобные конструкции: .toLatin1().data();
Несколько раз обсуждалось, что так делать не стоит.
Записан
Zmeishe
Гость
« Ответ #11 : Октябрь 20, 2009, 15:34 »

Цитата: BRE
Поищи по форуму темы про подобные конструкции: .toLatin1().data();
Несколько раз обсуждалось, что так делать не стоит.
Знаю я. Просто для ecspertiza урезал код. Задача была показать, что со строками всё должно работать.

На самом деле если в базе данных создаёшь UDF с ключиком FREE_IT
следует делать так:

Код:
#include <QtCore/QtGlobal>
#include <QtCore/QUuid>
#include <ib_util.h>

extern "C"  __declspec(dllexport) char* ib_udf_createUUID()
{
  char *p, *buf;

  p = QUuid::createUuid().toString().toLatin1().data();
  buf = (char*) ib_util_malloc(64);

  затем перегоняешь из p в buf

  return buf;
}

Но это так, к сведению.

По поводу того, почему у меня конкретно эта функция работает, а у ecspertiza нет -
пока ничего определённого сказать не могу.

Записан
BRE
Гость
« Ответ #12 : Октябрь 20, 2009, 15:49 »

Вот у меня тоже такое впечатление:
создается такое впечатление как будто ваша DLL с UDF не линкуется со всякими QtCore

2 ecspertiza
Покажи пожалуйста код библиотеки с UDF + файл проекта (.pro)
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #13 : Октябрь 20, 2009, 16:05 »

Допустим вот так

*.cpp
Код:
#include <QtCore/QtGlobal>
#include <QDebug>

extern "C" __declspec(dllexport) char* tostring(char* str)
{
  QByteArray data(str);
  data = data.toBase64();

  char *p = new char();

  p = data.data();

  qDebug() << p;

  return p;
}

*.pro
Код:
QT -= gui
QT += core
TARGET = crqphudf
TEMPLATE = lib
DEFINES += CRQPHUDF_LIBRARY
SOURCES += crqphudf.cpp
HEADERS +=
CONFIG += release

что самое интересное, сейчас начал вызывать функцию просто из другой софтины
вот так
Код:
    typedef char* (*toBase)(char *);
    toBase tobase = (toBase) QLibrary::resolve("crqphudf","tostring");

    char* base = tobase("qwerty");

    qDebug() << "key" << base;

в этом месте
Код:
qDebug() << p;
получаю нормальный результат

а тут
Код:
qDebug() << "key" << base;

один символ, при этом если из длл-ки убрать QByteArray

и оставить просто
Код:
  char *p = new char();
  p = str;
  return p;

то все работает нормально Непонимающий


Записан
BRE
Гость
« Ответ #14 : Октябрь 20, 2009, 16:10 »

Из другой софтины функция находиться, а из базы нет?

На счет странностей:
char *p = new char();   // здесь ты выделил один байт и присвоил его указателю p
p = data.data();      // здесь ты указатель p настроил на другую область памяти (предыдущая память потерялась)
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.098 секунд. Запросов: 23.