powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Invalid floating operation при импорте dll
10 сообщений из 10, страница 1 из 1
Invalid floating operation при импорте dll
    #40025316
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть 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
Invalid floating operation при импорте dll
    #40025328
Dovran184
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Огласите версию Delphi...
...
Рейтинг: 0 / 0
Invalid floating operation при импорте dll
    #40025333
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dovran184
Огласите версию Delphi...
Rio. Компиляция под x64
dll собирается на VS2019
...
Рейтинг: 0 / 0
Invalid floating operation при импорте dll
    #40025334
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Invalid floating operation при импорте dll
    #40025357
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо. Или из C
Код: plaintext
1.
_control87(EM_INVALID, EM_INVALID);
...
Рейтинг: 0 / 0
Invalid floating operation при импорте dll
    #40025366
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переписал сишную функцию в таком виде
Код: 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
Invalid floating operation при импорте dll
    #40025369
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_, Только учтите, что такой код НЕ потокобезопасен.
...
Рейтинг: 0 / 0
Invalid floating operation при импорте dll
    #40025388
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_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
Invalid floating operation при импорте dll
    #40025428
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён
Код: pascal
1.
Set8087CW(SavedCW or $7);

Это работать не будет. У меня Get8087CW уже возвращает $27F. Or $7 ничего не изменит
zedxxx
Только учтите, что такой код НЕ потокобезопасен.
Буду надеяться, что больше к сопроцессору никто не полезет. Других вариантов решения я не вижу
...
Рейтинг: 0 / 0
Invalid floating operation при импорте dll
    #40025431
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эээ... так сопроцессор в 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
10 сообщений из 10, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Invalid floating operation при импорте dll
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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