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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вопрос по DLL  (Прочитано 7681 раз)
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« : Сентябрь 20, 2009, 12:16 »

WINDOWS 2000,VC6, QT3.3.8

Есть DLL стороннего разработчика.
Загружаю DLL через QLibrary

Описал
Код:
QLibrary *lib_ims;
// установить кодовую страницу
typedef int (*My_ims_set_input_coding)    (int  coding);
My_ims_set_input_coding g_ims_set_input_coding;

Вызвал
Код:
QString path=qApp->applicationDirPath(); 
lib_ims= new QLibrary(path+"/ims");
bool f=lib_ims->isLoaded();
if (!f) f=lib_ims->load();
if (f)
{
g_ims_set_input_coding=(My_ims_set_input_coding)lib_ims->resolve("ims_set_input_coding");
if (g_ims_set_input_coding)
g_ims_set_input_coding(CP_WIN);
}

Библиотека грузится, функцию находит, но при вызове функции валится
http://img37.imagevenue.com/img.php?image=38074_err_122_428lo.JPG

Где я накосячил?
С DLL раньше работать не приходилось
Записан

Как мало времени и как много нужно узнать
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Сентябрь 20, 2009, 12:55 »

1) Ничто не спасет если не бьется по параметрам, ims_set_input_coding должна принимать 1 аргумент int

2) Попробовать "дела давно минувших дней"

typedef int (pascal *My_ims_set_input_coding)    (int  coding);
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #2 : Сентябрь 20, 2009, 13:04 »

1) Ничто не спасет если не бьется по параметрам, ims_set_input_coding должна принимать 1 аргумент int

2) Попробовать "дела давно минувших дней"

typedef int (pascal *My_ims_set_input_coding)    (int  coding);



1) Я и передаю int, CP_WIN это из enum;
2) поробовал
C:\SEP\form2.ui.h(29) : error C4226: nonstandard extension used : 'pascal' is an obsolete keyword
Записан

Как мало времени и как много нужно узнать
Rcus
Гость
« Ответ #3 : Сентябрь 20, 2009, 13:26 »

В windows стандартным соглашением вызова является stdcall (а функции без дополнительных указаний объявляются как cdecl), надо ее первым делом опробовать.
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #4 : Сентябрь 20, 2009, 13:30 »

В windows стандартным соглашением вызова является stdcall (а функции без дополнительных указаний объявляются как cdecl), надо ее первым делом опробовать.
А как это должно выглядеть в моем случае, если не сложно...
Записан

Как мало времени и как много нужно узнать
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Сентябрь 20, 2009, 13:49 »

А как это должно выглядеть в моем случае, если не сложно...
typedef int (_stdcall *My_ims_set_input_coding)    (int  coding);

У меня на VS 2008 pascal проходит и ничего про obsolete не говорит  Улыбающийся
Хотя. наверное, правильно _stdcall (справа налево)
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #6 : Сентябрь 20, 2009, 13:54 »

А как это должно выглядеть в моем случае, если не сложно...
typedef int (_stdcall *My_ims_set_input_coding)    (int  coding);

У меня на VS 2008 pascal проходит и ничего про obsolete не говорит  Улыбающийся
Хотя. наверное, правильно _stdcall (справа налево)


Спасибо
Код:
typedef int (_stdcall *My_ims_set_input_coding)(int  coding); 
сработало
Записан

Как мало времени и как много нужно узнать
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #7 : Сентябрь 27, 2009, 12:26 »

Igors, что то не могу сообразить, как описать вызов в LINUX
Записан

Как мало времени и как много нужно узнать
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Сентябрь 27, 2009, 12:58 »

Igors, что то не могу сообразить, как описать вызов в LINUX
Не отвечу потому что Linux ни разу даже не видел Улыбающийся
Но в любом случае можно "подсмотреть" как это делается для API функции. Например для Вындоуз мы знаем что какая-то функция сидит в dll. Смотрим как она описана.
Код:
HWND
WINAPI
GetWindow(
    __in HWND hWnd,
    __in UINT uCmd);
 
Смотрим что такое WINAPI

Код:
#define WINAPI      __stdcall
Ага, значит здесь __stdcall. Метод годится для любой платформы
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #9 : Сентябрь 27, 2009, 13:23 »

спасибо
Записан

Как мало времени и как много нужно узнать
Alchazar
Гость
« Ответ #10 : Февраль 10, 2010, 15:08 »

Никак не получается вызвать функцию из длл:
.cpp
Код
C++ (Qt)
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QSettings>
#include <QLibrary>
#include "WMI_access.h"
 
void MainWindow::getRamInfo()
{
   //QString ramCount;
   QLibrary wmi_lib("WMI_access");
   wmi_lib.load();
   if (wmi_lib.isLoaded())
       qDebug() << "Loaded";
   else
       qDebug() <<"Not Loaded";
 
   typedef clRamData(_stdcall *myRamInfo)();
   myRamInfo ramData = (myRamInfo)wmi_lib.resolve("ramData");
 
   if (ramData)
   {
       qDebug() << "ok??";
       clRamData ramInfo;
       ramInfo = ramData();
       qDebug() << "ram available: " <<ramInfo.ramAvailable;
   }
   else qDebug() << "error";
}

WMI_access.h
Код
C++ (Qt)
#ifndef __WMI_ACCESS_H
#define __WMI_ACCESS_H
 
#include <iostream>
#include <string>
using namespace std;
 
   class clCpuData
{
public:
string cpuManufacturer;
string cpuName;
int cpuLoadPercentage;
int cpuMaxClockSpeed;
int cpuNumberOfCores;
int cpuNumberOfLogicalProcessors;
int cpuNumberOfProcessors;
string cpuError;
};
 
class clHddData
{
public:
string hddName;
int hddRRER_trsh; //Raw Read Error Rate
int hddRRER;
int hddSUP_trsh; //Spin Up Time
int hddSUP;
int hddSSC_trsh; //Start/Stop Count
int hddSSC;
int hddRSC_trsh; //Reallocated Sector Count
int hddRSC;
int hddSER_trsh; //Seek Error Rate
int hddSER;
int hddPOTC_trsh; //Power On Time Count
int hddPOTC;
int hddSRC_trsh; //Spin Retry Count
int hddSRC;
int hddPCC_trsh; //Power Cycle Count
int hddPCC;
int hddT_trsh; //Temperature
int hddT;
int hddECC_trsh; //Hardware ECC Recovered
int hddECC;
int hddCPSC_trsh; //Current Pending Secotr Count
int hddCPSC;
int hddUSC_trsh; //Off line Uncorrectable Sector Count
int hddUSC;
int hddCRC_trsh; //Ultra ATA CRC Error Rate
int hddCRC;
int hddWER_trsh; //Write Error Rate
int hddWER;
string hddError;
};
 
class clRamData
{
public:
double ramCount;
long ramAvailable;
string ramError;
};
 
class clWMI_access_fn
   {
public:
 
               __declspec(dllexport) clHddData hddData();
__declspec(dllexport) clCpuData cpuData();
__declspec(dllexport) clRamData ramData();
 
   };
 
 
#endif /* __WMI_ACCESS_H*/

Длл писал сам в Visual C++, это моя первая длл'ка, но вроде всё сделал правильно.

В Application output получаю
Код:
Starting Q:\Darbai\HTMON\Client\client\debug\client.exe...
Loaded
error

Записан
Alchazar
Гость
« Ответ #11 : Февраль 11, 2010, 12:40 »

Получилось добраться до функции в длл файле, теперь программа вылетает когда я пытаюсь вызвать функцию
Код
C++ (Qt)
class clRamData
       {
       public:
           double ramCount;
           long ramAvailable;
           QString ramError;
       };
 
typedef clRamData(_stdcall *fnRamData)();
 
void MainWindow::getRamInfo()
{
   QLibrary wmi_lib("WMI_access");
   wmi_lib.load();
   if (wmi_lib.isLoaded())
       qDebug() << "Loaded";
   else
       qDebug() <<"Not Loaded";
 
   fnRamData fn_ramData;
   fn_ramData = (fnRamData)wmi_lib.resolve("ramData");
 
   if (fn_ramData)
   {
       qDebug() << "ok..";
       clRamData ramInfo;
       qDebug() << "class created..";
       ramInfo = fn_ramData(); // тут программа вылетает....
       qDebug() << "function called..";
       qDebug() << "ram available: " << ramInfo.ramAvailable;
   }
   else qDebug() << "error";
}
Если закоментировать две строчки:  
Код
C++ (Qt)
qDebug() << "function called..";
qDebug() << "ram available: " << ramInfo.ramAvailable;
то програмка запускается....
Я так понимаю, проблемма в том, что длл требует времени чтобы выполнить свою работу, а программа  не даёт ему (длл) достаточно времени, на это. Поэтому программа и вылетает.
Как можно узнать когда длл будет готов дать ответ?

методом тыка удалось запустить программу, добавил ещё одну строчку
Код:
qDebug() << "ram count: " << ramInfo.ramCount;
и программа начала запускаться... вот только результат совсем не в тему получается
ram available:  0
ram count:  5.28063e-308

Что-то я никак не пойму где тут собака зарыта....
« Последнее редактирование: Февраль 11, 2010, 17:40 от Alchazar » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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