Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Не получается согласовать работу приложения и dll


Автор: Курсант 5.6.2011, 18:09
Здравствуйте!

Суть проблемы - есть dll, в ней три функции, все три возвращают тип данных float, параметров не принимают. Одна из функций (вторая) возвращает единицу. Подключаюсь динамически к dll, получаю указатели на все три функции. Поочередно вызываю их и вывожу получаемые от них значения на график. В итоге вторая функция возвращает единицу, а первая и третья - нуль (Хотя нуль они не могут возвращать).
На случай если правильно удалось подключиться только к второй функции, поменял в исходнике dll логику второй функции, чтобы она выдавала всякие дробные значения - в итоге и вторая функция стала выдавать нуль. Вопрос - что за глюк? Может это разные формы представления типа float в dll и в моей программе?  dll скомпилирована на gcc, а программа в C++ Builder 6.0. 
З.ы. На предыдущей программе все работало, но я потерял исходники и теперь переписываю заново, и вот, такой глюк :(
Исходник прилагаю...
Код

   // Моделируем процесс во времени с шагом fStep
   for (float t=fFrom; t<=fTo; t += fStep) {
       // В библиотеке вызываем изменение состояния объекта, соответствующее интервалу времени fStep 
       DisturbSystem (fStep);
       // Теперь начинаем считывать параметры объекта после изменения состояния
       for (int i=0; i<iNumOfParams; i++) {
          int y = 1000*GetParams[i] ();  // Массив указателей на функцию из 3-х элементов. При этом 2-я функция всегда возвращает единицу.
          int iT = 1000*t;
          chtReaction->Series[i]->AddXY( iT, y ); // в итоге на графике получаю вторую прямую на уровне единицы и первую и третью прямые на уровне 0.
       }
   }

Автор: Курсант 5.6.2011, 18:50
Я использовал при загрузке библиотеки LoadLibrary... А в библиотеке используются глобальные переменные... Может ли быть, что LoadLibrary - неподходящая функция для запуска dll и ее работы с собственными глобальными переменными?

Автор: borisbn 5.6.2011, 18:54
Прописан ли явно тип вызова функций (__cdecl, __stdcall)?
Если нет, то нужно прописать. 

Автор: Курсант 5.6.2011, 19:23
Спасибо за ответ. Прописан __stdcall. Пробовал по-всякому.. и __fastcall, и __stdcall, и __cdecl, и WINAPI, и везде одно и то же получается.
Сейчас удивился в очередной раз. Вывожу глобальную переменную времени из библиотеки таким же образом - время отсчитывается нормально (т.е. глобальная переменная времени в библиотеке накапливается). При этом время инкрементируется на стотысячные доли секунды...
Все больше склоняюсь к тому, что форма представления чисел с плавающей точкой разная, но ведь это наверняка процессорный стандарт, и никак он различаться не может...

Судя по наблюдениям, в ноль обращаются переменные, при вычислении которых в библиотеке используется операция умножения... Может и правда мантиссы как-то переподгоняются при умножении..

Автор: borisbn 5.6.2011, 22:20
Покажи исходники функций из библиотеки. И ещё: а как ты объединил чисто линуксовый gcc и чисто виндузёвый builder? Или ты имел в виду minGW?

Автор: afiskon 5.6.2011, 22:28
В отладчике (каком-нибудь OllyDbg) посмотреть, что происходит, можете? Пробовали собрать библиотеку и программу одним компилятором? Проблема только с float, или также с double?

Автор: Курсант 6.6.2011, 19:05
эммм... пока проблема только с float... использовать один компилятор для библиотеки и для программы я не могу - к программе подключаются разные библиотеки. У всех у них одинаковые по названию функции внутри, но разный алгоритм преобразования. И компилировать их просто необходимо в gcc. А программа писана в Builder'e и если бы был способ эту программу компилировать с помощью gcc, я бы откомпилировал...

Может попробовать другой Builder? У меня есть старая программа, тоже на Builder'e, но кажется с другого дистрибутива... Там, на этой программе, все работает... А на новой - не работает...

Библиотеку прилагаю... model.c
Код

#include<math.h>

float K;
float A, B, C;
float x, g;
float y;
float t;

void ClearVariables () {
t=0;
K=2;
x = 2;
}

void DisturbSystem (float dt) {
g=1;
A = 1;
B = K*dt;
C = 1;
x = A*x+B*g;
y = C*x;
t += dt;
}

float GetParam0(){
return y;
}

float GetParam1(){
return g;
}

float GetParam2(){
return t;
}

float GetParam3(){
return A;
}


model.h
Код

#define EXPORT __declspec(dllexport)
EXPORT void ClearVariables ();
EXPORT void DisturbSystem (float);
EXPORT float GetParam0();
EXPORT float GetParam1();
EXPORT float GetParam2();
EXPORT float GetParam3();


Добавлено через 1 минуту и 33 секунды
всмысле, с double я пока не проверял. Попробую сделать отладку в Olly, о результатах отпишусь позже...

Автор: borisbn 6.6.2011, 19:45
Всё-таки явного типа вызова у тебя нет…
Так как у тебя получилось объединить чисто линуксовый и чисто виндузёвый компилятор? 

А ClearVariables точно вызывается? 

Автор: Курсант 6.6.2011, 21:31
Не знаю насчет подружить - я использую компилятор gcc для windows...
Проверяю насчет вызова ClearVariables...

Добавлено через 2 минуты и 47 секунд
Блин smile)) Йолки палки smile Только не бейте ) Только не ногами smile Только не по лицу smile

Я забыл вызвать ClearVariables... Все заработало smile Спасибо всем )) 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)