Перейти к содержанию
  • 0
Pulsarius

C++ Builder и BORLNDMM

Вопросы

Привет всем!
 

Кто-нибудь уже заметил, что приложения для десктоп, скомпилированные в последней версии C++ Builder (RAD Studio 10 Seattle), стали зависеть от BORLNDMM.dll? В предыдущих версиях студии такого не было. Я знаю, что это Борландовская библиотека для работы с памятью, и от неё зависели программы, написанные на ранних версиях C++ Builder, ещё будучи при Борланде. Чем же интересно обосновано возвращение такой зависимости и можно ли как-нибудь от неё избавиться?
 
P.S. Я пишу DLL. Пробовал избавиться от зависимости, отключив в настройках проекта "Use 'classic' Borland compiler", т.е. чтобы использовать Clang. Пришлось немного отредактировать код. Зависимость исчезла, но, при выгрузке моей DLL в главной программе функцией FreeLibrary, вылетает ошибка типа access violation. Такая ошибка возникает только тогда, когда DLL скомпилирована в режиме Release, в режиме Debug всё работает нормально, и поэтому отследить в чём дело очень сложно. Когда возникает ошибка, при отладке главной программы, отладчик перебрасывает в окно дизассемблера, где вместо ассемблерных команд знаки вопроса. Т.е. такое ощущение, что при вызове функции FreeLibrary, в каком-то месте происходит "прыжок" на адрес в памяти, где нет никаких инструкций. Если скомпилировать DLL с использованием классического компилятора Borland, то и в режиме Debug, и в режиме Release всё работает нормально.

Поделиться сообщением


Ссылка на сообщение

Рекомендуемые сообщения

  • 0
интересно обосновано возвращение такой зависимости и можно ли как-нибудь от неё избавиться?

 

 

Это баг. Обсуждалось здесь:

https://forums.embarcadero.com/thread.jspa?threadID=117351&tstart=15

Может исправят в первом апдейте, а может и нет.

Поделиться сообщением


Ссылка на сообщение
  • 0

Спасибо большое за ответы! Проблема решена. CFF Explorer помог. Я так понял, что идёт статическая линковка BORLNDMM.dll, но ни одна функция от туда не вызывается. Т.е. получается бесполезная зависимость от этой борландовской библиотеки. Обидный баг конечно. Такое ощущение, что специально делают такие якобы нечаянные и нелепые баги в билдере, вынуждая переходить на Delphi. Т.к. в Delphi таких нелепых багов я не встречал.
В ходе написания DLL я заметил, что есть ещё один скорее всего баг, при работе с TFDQuery (FireDAC). Свойство RecordCound имеет  значение 50 всегда, когда количество записей по факту больше 50-и. Решается это вызовом метода Refresh.

Поделиться сообщением


Ссылка на сообщение
  • 0

Насчет принуждения перехода к дельфи это вряд ли. Зачем тогда они развивают Builder?Например попытка добавить поддержку стандарта С++11. Проблема в не желании тестировать свои релизы.

А насчтет FireDAC, FetchAll вызываете при запросе?

Отредактировал Kitty

Поделиться сообщением


Ссылка на сообщение
  • 0

Нет, не вызывал. Прочитал в хелпе про FetchOptions, выставил FetchOptions.Manual = fmAll и теперь всё работает как надо. Только не пойму смысла. Если эта опция отвечает якобы за ограничение получения записей, то почему по факту в TFDQuery количество записей было больше выставленного максимума, т.е. все записи, которые возвращает мне запрос? По идее в данном случае в память DataSet не должно было грузиться более 50 записей. А так получается смысла в этой опции нет, она только не даёт свойству RecordCount стать выше установленного максимума, а в DataSet всё равно грузятся все записи, возвращённые запросом, и пройтись по ним можно вызывая в цикле Next() пока свойство Eof не будет истинным.

Отредактировал Pulsarius

Поделиться сообщением


Ссылка на сообщение

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Похожий контент

    • От neo
      Ребята здарова!
      выручайте) весь уже измучился =( не получается =(
      Тема такая, работаю с хуком, использую WH_KEYBOARD_LL
      тк нужно работать и с 32 битной и 64 битной разрядностью.
      и вообще мне нравится с ним работать всё очень просто и удобно но появилось одно НО =(
      WH_KEYBOARD_LL работает до добавления сообщения в очередь в контексте потока.
      и это действительно так =(
      дело в том что я через хук ловлю введённую информацию и потом обрабатываю это через
      idHTTP (ищу в интернете ответ)... если сигнал хороший то всё круть... а когда связь не очень..
      и происходят небольшие задержки..
      как я понимаю в WH_KEYBOARD_LL складируются результаты которые он не может передать
      и затем хук выбивается... тоесть чтобы всё вновь заработало нужно сделать так
       
      KeyboardHandle:=SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, HInstance, 0);
      и хук по прежнему работает до тех пор пока не вылетит вновь.
      Чтобы решить эту проблему как я понял нужно использовать PeekMessage или GetMessage
      и удалять излишки... Но в сети очень мало информации о том как ими пользоваться я не понимаю
      куда и как их вставлять.
      Я делал вот так... писал в ДЛЛке
      function KeyboardHook(code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
      var
      msg:TMsg;
      begin
       if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then exit;
       if code>=0 then
        begin
          if (wParam=WM_KEYDOWN) then
          begin
          SendMessage(FindWindow('TForm1', 'Form1'), KeyboardEvent, 0,PBDLLHOOKSTRUCT(lParam).vkCode);
          end;
        end;
        Result:=CallNextHookEx(KeyboardHandle, code, wParam, lParam)
      end;
      // if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then exit;
      // типа если есть излишки выходи

      так же вставлял там это:
          while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
          begin
              TranslateMessage(Msg);
              DispatchMessage(Msg);
            end;
      но не помогает =(
      Может это где-то в ЕХЕшнике нужно вставлять? я не понимаю как с ним работать =(
      Может кто на форуме знает? помогите пожалуйста ответом
    • От Pulsarius
      Привет, форумчане! Я уже как-то задавал подобный вопрос, но видимо никто не сталкивался с этим. Может быть сейчас кто-нибудь столкнулся. Эта проблема качует из версии в версию и никто не исправляет это, а может быть я что-то не всё правильно делаю. Конкретнее, я в своём проекте использовал TcxPageControl от DevExpress и TFDConnection, TFDQuery от FireDAC. Теперь я удалил эти элементы из своего проекта, совершенно нигде не использую TcxPageControl и приложение у меня теперь не коннектится напрямую с базой данных. Вручную почистил все #include и #pragma link, но линковщик C++ Builder мне всё равно усердно впихивает cxPageControlRS25.bpl и firedac250.bpl в exe-шник. Если делать Deployment на удалённую машину с динамическими зависимостями от рантаймов, то соответственно туда тоже копируются эти ненужные cxPageControlRS25.bpl и firedac250.bpl. Открыл проект *.cbproj как текст и увидел там эти самые названия. Можно конечно вручную тоже их поудалять, но есть ли какой-то адекватный способ удаления зависимостей от уже ненужных библиотек, что бы вручную не выкосить что-нибудь лишнее? Это я как пример всего две bpl упамянул, а на самом деле там больше, ведь DevExpress и FireDAC там за собой тащат ещё кучу всяких bpl, типа там dxCore.bpl, datadb.bpl и т.п. Вот и происходит такая мусорка в скомпилированном файле и размер соответственно напрасно большой делается. В Visual Studio я с подобным не сталкивался.
    • От Pulsarius
      Здравствуйте, Ярослав! Скажите, пожалуйста, есть ли какая либо информация о планах поддержки Linux в C++ Builder? Нашей компании очень подходит RAD Studio для наших целей и быстрой разработки. Планируем приобрести лицензию. В ближайшее время планируем разрабатывать наше решение для Windows, macOS и Android, пока этого достаточно. Но есть некоторые сомнения о выборе RAD Studio и всё из-за того, что примерно через год потребуется наше решение реализовать и для Linux. Какова вероятность, что C++ Builder обзаведётся поддержкой Linux'а в течении 1 - 1,5 года? Delphi не рассматриваем. Заранее спасибо за ответ.
    • От notricky
      Интересует вопрос и ноу-хау.
      Если есть код на Питоне, который нужно выполнять в рамках Андроид и айОС приложений - как это лучше всего делать и как это будет выглядеть?
      Читал, что есть Python4Delphi и это речь про DLL. Хотелось бы понять, как это будет выглядеть на iOS и Android - это дополнительный файл надо с собой такскать как в Windows или он будет внутри APK/APP ?
    • От bigjorj
      Win32 приложение на Firemonkey
      Есть DLL написанная на C++. В ней есть экспортная функция.
      int getStatusFlags (int *fatalStatus, int *currentFlagsStatus, int *documentStatus); импортирую функцию следующим способом 
      function getStatusFlags (var fatalStatus, currentFlagsStatus, documentStatus:Integer):integer; stdcall; external DllName; В режиме компиляции Debug все идеально, но если откомпилировать в Release то приложение наглухо виснет при вызове функции.
      Подозреваю что я неправильно импортирую функцию и происходит неправильная работа с памятью. Пробовал менять тип передаваемых переменных на PInteger с передачей указателей, но все равно падает.
      Кто сталкивался. Помогите!
       
       
       
       
    • От ivadimos
      Есть какой-то базовый класс. Необходимо расширить его функционал и вынести во внешний модуль(плагин). Модуль необходимо подгружать динамически из папки. 
      Каким образом могу это реализовать? 
    • От MolarMak
      Всем доброго времени суток, столкнулся с такой проблемой, на определенной форме включается медиаплеер и начинает проигрывать определенный трек, но при блокировке трек продолжает играть. Как обработать событие блокировки экрана и по нему отключать медиаплеер? Пишу на c++ builder.
      Пробовал делать через EnteredBackground, руководствовался заметкой по написанию подобного на Delphi xe http://delphifmandroid.blogspot.com/2013/10/blog-post.html
      Возможно есть другие варианты решения?
    • От Pulsarius
      Привет всем! Скажите, кто-нибудь сталкивался с проблемой компиляции проекта с использованием FireDAC в C++ Builder (RAD Studio 10 Seattle) под Windows 64-bit? В проекте есть такие компоненты, как TFDConnection, TFDQuery, TFDTable. TFDConnection настроен на работу с SQLite. При компиляции в режиме Release, естественно с отключенными Dynamic RTL и Link with runtime packages, под Windows 32-bit всё в порядке, а вот под Windows 64-bit происходит ошибка, как я понял, линковщика:
      [ilink64 Warning] Warning: Out of memory [ilink64 Error] "ilink32" exited with code 2. Мне так кажется, что нет статических библиотек FireDAC для Windows 64-bit, и тем самым не удастся собрать проект со статической линковкой нужных либ, а только придётся таскать нужные библиотеки за exe-шником. Я правильно понимаю?
    • От Platon
      Вообще несколько вопросов по данной теме, буду рад если тыкните на документацию embarcadero.
      В данный момент apk моего приложения весит ~90мб и помещается оно на sd-карту.
       
      1. Сколько весит пустой apk с одной формой?
      2. Как устанавливать apk на телефон? Где можно это указать в IDE?
      3. Как можно уменьшить размер apk? Убрать лишние библиотеки? Может как-то еще? 
      4. В своем приложении я использую много картинок, каждая в среднем занимает ~100кб. Это нормальный размер для картинок? Или можно и лучше использовать меньший размер? Но тогда качество будет ужасным.
    • От Alexander616
      Помогите пожалуйста разобраться с кодом С#, в коде загружается dll и используются функции из неё, хочу перевести на дельфи.
       
      загрузка dll
      [DllImport("opus.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr opus_decoder_create(int Fs, int channels, out IntPtr error); [DllImport("opus.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern void opus_decoder_destroy(IntPtr decoder); [DllImport("opus.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_decode(IntPtr st, byte[] data, int len, byte[] pcm, int frame_size, int decode_fec); public static OpusDecoder Create(int outputSampleRate, int outputChannels) { if (outputSampleRate != 8000 && outputSampleRate != 12000 && outputSampleRate != 16000 && outputSampleRate != 24000 && outputSampleRate != 48000) throw new ArgumentOutOfRangeException("inputSamplingRate"); if (outputChannels != 1 && outputChannels != 2) throw new ArgumentOutOfRangeException("inputChannels"); IntPtr error; IntPtr decoder = API.opus_decoder_create(outputSampleRate, outputChannels, out error); if ((Errors)error != Errors.OK) { throw new Exception("Exception occured while creating decoder"); } return new OpusDecoder(decoder, outputSampleRate, outputChannels); } public unsafe byte[] Decode(byte[] inputOpusData, int dataLength, out int decodedLength) { if (disposed) throw new ObjectDisposedException("OpusDecoder"); byte[] decoded = new byte[MaxDataBytes]; int frameCount = FrameCount(MaxDataBytes); int length = 0; if (inputOpusData != null) length = API.opus_decode(_decoder, inputOpusData, dataLength, decoded, frameCount, 0); else length = API.opus_decode(_decoder, null, 0, decoded, frameCount, (ForwardErrorCorrection) ? 1 : 0); decodedLength = length * 2; if (length < 0) throw new Exception("Decoding failed - " + ((Errors)length).ToString()); return decoded; } private void button3_Click(object sender, EventArgs e) { OpusDecoder _dec= OpusDecoder.Create(48000, 1); byte[] segDec = new byte[4000]; byte[] seg = new byte[4000]; seg[0] = 8; seg[1] = 11; seg[2] = 230; seg[3] = 61; seg[4] = 36; seg[5] = 236; seg[6] = 195; seg[7] = 220; seg[8] = 192; int len = 9; segDec = _dec.Decode(seg, len, out len); } код на C# работает, но когда перевожу его на дельфи он начинает ругаться "stackoverflow"
       
      загрузка dll
      function opus_decoder_create(Fs:LongInt; channels:Integer; var Error:Integer):OpusDecoder; cdecl; external 'opus.dll'; function opus_decode(st:OpusDecoder; data:array of Byte; len:Integer;var pcm: array of Byte; frame_size: Integer; decode_fec:Integer):Integer; cdecl; external 'opus.dll'; procedure opus_decoder_destroy(st:OpusEncoder); cdecl; external 'opus.dll'; использование функций
      procedure TMain.Decode_2Click(Sender: TObject); var OPDecoder: OpusDecoder; Error: Integer; PreEnc:array of Byte; PreDec:array of Byte; begin Error := 0 ; OPDecoder := opus_decoder_create(48000, 1, Error); SetLength(PreEnc, 4000); SetLength(PreDec, 4000); PreEnc[0] := 8; PreEnc[1] := 11; PreEnc[2] := 230; PreEnc[3] := 61; PreEnc[4] := 36; PreEnc[5] := 236; PreEnc[6] := 195; PreEnc[7] := 220; PreEnc[8] := 192; Error := opus_decode(OPDecoder, PreEnc, 9, PreDec, 2000, 0); end; в процедуру dll ки значения подаются одинаковые в обеих случаях, никак не могу разобраться в чём дело.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...