Вітаю всіх. У сьогоднішній статті мова піде про те, як можна реалізувати власний високорівневий API в керованому коді для роботи з пристроями друку, від встановлення нового монітора друку в системі і до отримання обробленого драйвером пристрою друку документа з порту принтера.

Як і в минулий раз, стаття буде корисна для ознайомлення розробникам молодшого та середнього ланки. В процесі вивчення матеріалу, Ви дізнаєтеся як можна звертатися до низькорівневим DLL WinAPI в C# з допомогою P/Invoke, як встановити, налаштувати і видалити з системи монітори друку, драйвер принтера, сам пристрій друку, відкрити і зв'язати порт для перенаправлення вхідних даних з пристрою друку на монітор, познайомитеся з ключовими моментами застосування маршалирования. Так само ми на практичному прикладі розберемося, як за допомогою нашого API можна зручно маніпулювати пристроями друку в системі, дізнаємося, як можна перехопити оброблені дані після друку принтера і, наприклад, відправити їх на сервер.

Читати далі →

Пошук витоку GDI об'єктів: Як загнати мастодонта

Строго кажучи саме це оригінальний текст статті, а в блог вже переклад. Тут стаття публікується трохи пізніше і тільки тому отримує бирку переклад.

В 2016 році, коли більшість програм виконуються в пісочницях, з яких навіть самий некомпетентний розробник не зможе нашкодити системі, дивно стикатися з проблемою, про яку далі піде мова. Якщо чесно, я сподівався, що вона пішла в далеке минуле разом з Win32Api, але недавно я з нею зіткнувся. До цього я лише чув страшні байки старих більш досвідчених розробників, що таке може бути.

Проблема
Витік або використання занадто великої кількості GDI об'єктів.

Симптоми:
  • Task Manager на вкладці Details колонка GDI objects показує загрозливі 10000(Якщо цієї колонки немає, її можна додати, натиснувши на заголовку таблиці правою кнопкою миші і вибравши пункт Select Columns)
  • При розробці на C# або іншою мовою виконуваному CLR полетить виняток, далеко не нова конкретикою:
    Message: A generic error occurred in GDI+.
    Source: System.Drawing
    TargetSite: IntPtr GetHbitmap(System.Drawing.Color)
    Type:System.Runtime.InteropServices.ExternalException
    Також при певних налаштуваннях або версії системи виключення може і не бути, але Ваш додаток не зможе намалювати жодного об'єкта.
  • При розробці на З/З++ всі методи GDI начебто Create%SOME_GDI_OBJECT% стали повертати NULL

Читати далі →

Доріг чи native метод? «Секретна» розширення JNI

    
Для чого Java-програмісти вдаються до native методів? Іноді, щоб скористатися сторонньою DLL бібліотекою. В інших випадках, щоб прискорити критичний алгоритм за рахунок оптимізованого коду на C або асемблері. Наприклад, для обробки потокового медіа, для стиснення, шифрування і т.п.
 
Але виклик native методу не безкоштовний. Часом, накладні витрати на JNI виявляються навіть більше, ніж виграш в продуктивності. А все тому, що вони включають в себе:
 
     
  1. створення stack frame;
  2.  
  3. перекладання аргументів відповідно до ABI ;
  4.  
  5. огортання посилань в JNI хендла (
    jobject
    );
  6.  
  7. передачу додаткових аргументів
    JNIEnv*
    і
    jclass
    ;
  8.  
  9. захоплення і звільнення монітора, якщо метод
    synchronized
    ;
  10.  
  11. «ледачу» лінковку нативной функції;
  12.  
  13. трасування входу і виходу з методу;
  14.  
  15. переклад потоку зі стану
    in_Java
    в
    in_native
    і назад;
  16.  
  17. перевірку необхідності safepoint;
  18.  
  19. обробку можливих винятків.
  20.  
Але найчастіше native методи прості: вони не кидають винятків, не створюють нові об'єкти в купі, не оминають стек, не працюють з хендлов і не синхронізовані. Чи можна для них не робити зайвих дій?
 
Так, і сьогодні я розповім про недокументованих можливостях HotSpot JVM для прискореного виклику простих JNI методів. Хоча ця оптимізація з'явилася ще з перших версій Java 7, що дивно, про неї ще ніхто ніде не писав.
 
Читати далі →