Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Invalid floating operation при импорте dll / 10 сообщений из 10, страница 1 из 1
07.12.2020, 16:12
    #40025316
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
Есть C++ классы, которые лежат в lib файле. Исходников у меня нет. На MSVS пишу тестовое консольное приложение
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
int main()
{
    uint16_t cw = get8087CW();
    std::cout << "CW: " << cw << "\n";  // 639
    TResult error;
    std::unique_ptr<CFramework> frame = CFramework::New(
        error,
        p "ukraine.ctm1",
        p "standard.ctstyle",
        p "DejaVuSans.ttf",
        800,
        600
    );
    cw = get8087CW();
    std::cout << "CW: " << cw << "\n";  // 639
    if (error == 0) {
        const TBitmap* bmp = frame->MapBitmap(error);
        std::cout << bmp->Width();
    }
}


Все работает. get8087CW оба раза возвращает 639 (0x27F)

Переношу эту функцию в dll
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
extern "C" __declspec(dllexport)  int32_t  __stdcall test();

int32_t test() {
    uint16_t cw = get8087CW();  // 639
    TResult error;
    std::unique_ptr<CFramework> frame = CFramework::New(
        error,
        p "ukraine.ctm1",
        p "standard.ctstyle",
        p "DejaVuSans.ttf",
        800,
        600
    );
    cw = get8087CW();  // 639
    if (error == 0) {
        const TBitmap* bmp = frame->MapBitmap(error);
    }
    return error;
}

На выделенной строке вылетает Invalid floating operation. get8087CW по прежнему возвращает 639

Из Delphi вызов такой
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function test(): Integer; stdcall; external 'test.dll' name 'test';

procedure TForm1.FormCreate(Sender: TObject);
var
  LCW: Word;
begin
  LCW := Get8087CW;  // 639
  try
    test;
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
  LCW := Get8087CW;  // 639
end;


Get8087CW опять возвращает 639

Куда копать?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
07.12.2020, 16:34
    #40025328
Dovran184
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
_Vasilisk_,

Огласите версию Delphi...
...
Рейтинг: 0 / 0
07.12.2020, 16:45
    #40025333
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
Dovran184
Огласите версию Delphi...
Rio. Компиляция под x64
dll собирается на VS2019
...
Рейтинг: 0 / 0
07.12.2020, 16:45
    #40025334
zedxxx
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
...
Рейтинг: 0 / 0
07.12.2020, 17:32
    #40025357
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
Спасибо. Или из C
Код: plaintext
1.
_control87(EM_INVALID, EM_INVALID);
...
Рейтинг: 0 / 0
07.12.2020, 17:51
    #40025366
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
Переписал сишную функцию в таком виде
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
if (error == 0) {
    unsigned int oldVal = _control87(0, 0);
    unsigned int newVal = _control87(EM_INVALID, EM_INVALID);
    __try {
        const TBitmap* bmp = frame->MapBitmap(error);
    }
    __finally {
        if (oldVal != newVal)
            _control87(oldVal, oldVal);
    }
}

...
Рейтинг: 0 / 0
07.12.2020, 18:02
    #40025369
zedxxx
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
_Vasilisk_, Только учтите, что такой код НЕ потокобезопасен.
...
Рейтинг: 0 / 0
07.12.2020, 18:58
    #40025388
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
_Vasilisk_,

14663956

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
var
   SavedCW: word;
begin
   SavedCW := Get8087CW;
   try
      Set8087CW(SavedCW or $7);
      
      //здесь LoadLibrary или вызов функций из DLLки
      //...
   finally
      Set8087CW(SavedCW);
   end;
...
Рейтинг: 0 / 0
07.12.2020, 21:47
    #40025428
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
Кроик Семён
Код: pascal
1.
Set8087CW(SavedCW or $7);

Это работать не будет. У меня Get8087CW уже возвращает $27F. Or $7 ничего не изменит
zedxxx
Только учтите, что такой код НЕ потокобезопасен.
Буду надеяться, что больше к сопроцессору никто не полезет. Других вариантов решения я не вижу
...
Рейтинг: 0 / 0
07.12.2020, 22:17
    #40025431
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Invalid floating operation при импорте dll
Эээ... так сопроцессор в x64 не используется. Там используется SSE. Это даже в доках к Get8087CW сказано:

Get8087CWOn 64-bit Windows: This control word does not control floating-point operations, because the SSE register is used for floating point in 64-bit mode, instead of the FPU.

Надо GetMXCSR .

GetMXCSRSystem.GetMXCSR returns the value of MXCSR SSE status and control register.

Note: To change the exception mode, the rounding mode, and the precision for floating-point numbers, we recommend that you use System.Math.SetExceptionMask, System.Math.SetRoundMode, and System.Math.SetPrecisionMode instead of System.Set8087CW or SetMXCSR.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Invalid floating operation при импорте dll / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]