Замечания и предложения


#387

А куда вы записываете поток ресурса?


#388

Немного изменил код и получил точное описание ошибки: поток имеет значение null. Библиотека:

library MyLib;
{$Resource 'Без названия (2).png'}
{$Reference 'System.Drawing.dll'}
{$Reference 'System.dll'}
{$Reference 'System.IO.dll'}
Uses System;
Uses System.IO;
Uses System.Drawing;
function GetBMP(): System.Drawing.Bitmap;
begin
  Result := new System.Drawing.Bitmap(System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream('Без названия (2).png'));
end;
End.

Программа:

{$Reference 'MyLib.dll'}
{$Reference 'System.Windows.Forms.dll'}
{$Reference 'System.Drawing.dll'}
{$Reference 'System.dll'}
begin
  var MainImage := MyLib.GetBMP();
  var MainForm := new System.Windows.Forms.Form;
  MainForm.ClientSize := MainImage.Size;
  MainForm.BackgroundImage := MainImage;
  System.Windows.Forms.Application.Run(MainForm);
end.

Исключение было вызвано в библиотеке из конструктора класса Bitmap. Текст: “MyLib.pas(11) : Ошибка времени выполнения: Значение ‘null’ недопустимо для ‘stream’.”.


#389

Да я тоже у себя попробовал, не работает только в библиотеках. Кстати System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream вроде можно заменить на GetResourceStream. А анализатор кода в основной программе с подключённой библиотекой сходит с ума, его вообще проверяли?


#390

Заменить можно, но я теперь практикую PABCSystem’о-замещение.:sunglasses:

А вот анализатор кода мне “открыл Америку”! Оказывается, что можно создавать экземпляры целых пространств имён! Пространственно-ориентированное программирование против объектно-ориентированного!


#391

Ну тогда напишите свою GetResourceStream и вставляйте в каждую программу потому что такие длинные строчки надо стараться избегать. А вообще байкот дело тупое. Пока на горизонте не видно и близко отключения PABCSystem - это лишь трата времени и сил.


#392

Я тут кое-что проверил. Короче, если ресурс определён в библиотеке, то программа крашится, а вот если ресурс определён в основной программе, то даже вызывая его из библиотеки, он нормально отрабатывает.

Программа:

{$reference 'md.dll'}
{$reference 'system.dll'}
{$reference 'system.drawing.dll'}
{$reference 'system.windows.forms.dll'}
{$resource 'Img.png'}

uses
   System,
      System.Drawing,
      System.Windows.Forms;

begin

   var MainForm: System.Windows.Forms.Form := new Form();
   MainForm.ClientSize := new Size(1280, 800);
   MainForm.BackgroundImage := md.md.getImageFromResource();
   System.Windows.Forms.Application.Run(MainForm);

end.

DLL:


{$reference 'System.dll'}
{$reference 'System.Drawing.dll'}

LIBRARY md;

interface

   uses
      System,
         System.Drawing;

   {$resource 'Img.png'}
   
   function getImageFromResource(): System.Drawing.Image;
   
implementation

   function getImageFromResource(): System.Drawing.Image;
      begin //1a
      
         Result := Image.FromStream(getResourceStream('Img.png'));
      
      end; //1a

end.


#393

Возможно тогда System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream не подходит и чтоб вытащить ресурсы из dll надо другую функцию? Ну то есть для основной программы и модулей информация в GetEntryAssembly а у dll файлов она отдельно? Поищите, у меня ещё не так много места в голове освободилось для изучения System.Reflection.Assembly ;).


#394

Это я тоже заметил, но ведь ресурс должен быть именно в библиотеке!


#395

Может быть, но в платформе .NET, по сути, различий между Dll, Exe и WinExe практически нет. Все откомпилированные результаты называются сборками. Тут, думаю, лучше спросить у Админа.


#396

Я всё же залез в асембли и оказался прав, вот dll:

library Lib;
{$Resource 'im.png'}
{$Reference 'System.Drawing.dll'}
{$Reference 'System.dll'}
{$Reference 'System.IO.dll'}
Uses System;
Uses System.IO;
Uses System.Drawing;

function GetBMP(): System.Drawing.Bitmap;
begin
  Result := new System.Drawing.Bitmap(System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream('im.png'));
end;
End.

При чём тут отличия, я говорю про то что это 2 разных хранилища подпрограмм и типов. И GetResourceStream пытается найти точку начала потока в exe файле а не в dll.


#397

Спасибо большое! Очень выручили!

Да, я перепутал…


#398

Таак, запись в блокнотике: взять на заметку при сборке .DLL с ресурсами :slight_smile:


#399

У Sequence of T есть функция Reverse без параметров. У List<T> тоже. Мне понадобилась функция List<T>.Reverse, но всегда вызывается первая. Мне казалось функцию должно подобрать по возвращаемому значению, но l := l.Reverse, где l:List<T> не работает.


#400

Здравствуйте. Можно ли реализовать отображение стека вызова подпрограмм (процедур и функций). И показать там значение переменных и т.д. Что поможет отлаживать программы. Данная идея возникла при объяснении детям темы “рекурсия”, и если бы этот функционал был - было бы проще не только преподавателям, но и ученикам отлаживать программы. Заранее Большое Спасибо!!!)


#401

Во вкладке вид есть меню Локальные переменные, вам это нужно?


#402

Было бы не плохо, если бы вы добавили кнопку (или сочетание клавиш) быстрого сворачивания всего кода, а то как-то не очень айс сворачивать каждый метод и каждую функцию (Весь раздел сворачивать не надо!).


#403

Стек вызовов позволяет подняться по вызовам наверх и посмотреть, к примеру, состояние локальных переменных, которые находятся в функциях, вызвавших ту, в которой мы стоим. Стандартная функциональность для любой IDE, к слову. Окошко “Локальные переменные” ее заменить не может.

суть (цифры - адреса положения инструкций в секции кода):

0: procedure p1();
1: begin
2:    var t1 := 1; //а сюда мы можем взглянуть с помощью стека вызовов
3:    p2();
4: end;
5: 
6: procedure p2();
7: begin
8:    var t2 := 2; // тут брейкпойнт
9: end;
...
100: p1();
...

Это возможно потому, что точки входа в функции кладутся на стек последовательно, и находятся в пределах известной и доступной памяти в любой момент исполнения. В данном случае (грубо):

...
[p1_parameters {нет}]
[return_address_to_p1_caller {100}]
[p1_local_variables {t1}]
[p2_parameters {нет}]
[return_address_to_p1 {3}]
[p2_local_variables {t2}] << вершина стека

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


#404

Да, это я видел, но если функция вызывается из другой функции или из самой себя, в этой вкладке видны только переменные текущей функции (где сейчас находится отладка). А хотелось бы видеть и значения переменных для функций которые привели к вызову текущей. Например программа:

procedure f(n:integer); begin _ if (n = 0) then exit;_ _ write(n,’ ');_ _ f(n - 1);_ end; begin _ f(3);_ end.

Хотелось бы видеть на момент отладки, когда n=0, т.е. процедура f была вызвана четвёртый раз что то подобное: 1) f(n = 3) 2) f(n = 2) 3 f(n = 1) 4 f(n = 0) То есть весь стек вызовов подпрограмм со значением входных и локальных переменных на текущий момент отладки. Большое спасибо за ответ!


#405

В PABCSystem на строчках 3403, 4187, 4194 при создании списка или словаря надо задавать ему начальный размер, это влияет на производительность.


#406

Ну тогда могу посоветовать на данном этапе использовать отладку “Шаг со входом в подпрограмму”, тогда в окне “Локальные переменные” вы сможете отслеживать стек на каждом шаге.