В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Всем привет!
Возникла потребность использовать внешнюю DLL из приложения на LV.
Раньше я использовать ее в среде LV2010 для печати картинки на принтер. У меня есть готовая и хорошо работает.
Сейчас я апгрейдил приложение на LV до платформы x64 бит, и хотел бы пересобрать и эту DLL, чтобы не изобретать велосипед.
Но с тех пор у Винды поменялся интерфейс в DLL файлах, и я не знаю: в какой среде переписать эту коротенькую утилитку: толи в CPP то ли в C#(.NET).
Или воспроизвести это в среде LV?
Вся задача: однобитный битмап (файл .BMP) распечатать на принтере в точках принтера.
Я бы предпочел это сделать в самой LV. Но пока не знаю: использование NIReport представляется очень громоздким.
И как в нем добиться, чтобы растровая картинка печаталась в точках принтера?
Возникла потребность использовать внешнюю DLL из приложения на LV.
Раньше я использовать ее в среде LV2010 для печати картинки на принтер. У меня есть готовая и хорошо работает.
Сейчас я апгрейдил приложение на LV до платформы x64 бит, и хотел бы пересобрать и эту DLL, чтобы не изобретать велосипед.
Но с тех пор у Винды поменялся интерфейс в DLL файлах, и я не знаю: в какой среде переписать эту коротенькую утилитку: толи в CPP то ли в C#(.NET).
Или воспроизвести это в среде LV?
Вся задача: однобитный битмап (файл .BMP) распечатать на принтере в точках принтера.
Я бы предпочел это сделать в самой LV. Но пока не знаю: использование NIReport представляется очень громоздким.
И как в нем добиться, чтобы растровая картинка печаталась в точках принтера?
-
dadreamer
- professor
- Сообщения: 3962
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 13 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: В какой средк (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Если в коде DLL в основном WinAPI вызывается, то будет не так сложно воспроизвести его на диаграмме с помощью вызовов CLFN. Однако, если там какие-то C- (и тем более C++) специфичные штуки заюзаны, то проще, наверное, перекомпилить под 64 бита. В общем, покажите код библиотеки, тогда можно будет сказать точнее.
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой средк (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
В этой старенькой DLL кода на две странички.
Прицепляю файлик на СРР.
Но проблема в том, что в этой старой редакции использовался класс CImage для чтения BMP_файла.
Теперь Windows его не поддерживает и надо искать альтернативу.
Я попытался сделать то же в LV2021 через NIReport.
Но он почему-то все время кидает на дефолтный принтер, что меня не устраивает. А когда я делаю принтер дефолтным, то виснет на отправке и все. Хотел макетик битмапа прицепить, но ругается на недопустимый файл.
Прицепляю файлик на СРР.
Но проблема в том, что в этой старой редакции использовался класс CImage для чтения BMP_файла.
Теперь Windows его не поддерживает и надо искать альтернативу.
Я попытался сделать то же в LV2021 через NIReport.
Но он почему-то все время кидает на дефолтный принтер, что меня не устраивает. А когда я делаю принтер дефолтным, то виснет на отправке и все. Хотел макетик битмапа прицепить, но ругается на недопустимый файл.
- Вложения
-
PrintBMP2.cpp
- (12.08 КБ) 132 скачивания
-
dadreamer
- professor
- Сообщения: 3962
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 13 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: В какой средк (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
В принципе, этот код несложно переписать на инструментах
, займёт где-то пол-часа - час работы. Но я попробовал скомпилировать в MS Visual Studio 2015 и особых граблей не вылезло. 64-битная версия тоже компилируется. Не знаю, как будет работать, нужно проверять. Вероятно, также потребует установки Microsoft Visual C++ 2015 Redistributable.

- Вложения
-
PrintBMP.rar
- (12.11 КБ) 181 скачивание
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Спасибо! Я сделал то же самое в VS2020.
Код простой и компилится без затей. Проблема в том, что чтение битмапа производится классом CImage.
И чтение файла однобитного (ч/б) битмапа в новой платформе всегда приводит к ошибке в этой строке. :-(
Хотя файл читают все графические программы.
Когда я вызываю справку по CImage, там написано, что на платформе Windows этот класс не поддерживается.
Но опыт работы с графикой в CPP у меня уже старый, тоже последний раз пользовался в VS2015.
Новая Винда теперь вся на платформе .Net. Поэтому и вопрос задал о среде разработки DLL.
Видимо, система классов теперь иная. Последний раз приходилось писать DLL в VS2020 в C# для работы с устройством DIO.
Правда, на платформе х32.
Но с графикой давно не работал.
Попробовал смастерить эту процедуру средствами LV через NI Report.
Работать работает, но результата нет: не видит указываемого принтера и фигачит на дефолтный. А мне надо на предписанный.
Но даже делая принтер дефолтным, ничего на него не вылазит и процедура виснет.
Теперь до понедельника буду кумекать.
Код простой и компилится без затей. Проблема в том, что чтение битмапа производится классом CImage.
И чтение файла однобитного (ч/б) битмапа в новой платформе всегда приводит к ошибке в этой строке. :-(
Хотя файл читают все графические программы.
Когда я вызываю справку по CImage, там написано, что на платформе Windows этот класс не поддерживается.
Но опыт работы с графикой в CPP у меня уже старый, тоже последний раз пользовался в VS2015.
Новая Винда теперь вся на платформе .Net. Поэтому и вопрос задал о среде разработки DLL.
Видимо, система классов теперь иная. Последний раз приходилось писать DLL в VS2020 в C# для работы с устройством DIO.
Правда, на платформе х32.
Но с графикой давно не работал.
Попробовал смастерить эту процедуру средствами LV через NI Report.
Работать работает, но результата нет: не видит указываемого принтера и фигачит на дефолтный. А мне надо на предписанный.
Но даже делая принтер дефолтным, ничего на него не вылазит и процедура виснет.
Теперь до понедельника буду кумекать.
-
dadreamer
- professor
- Сообщения: 3962
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 13 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
То, что на MSDN написано
к обычным приложениям Windows не относится. Это касается только программ на архитектуре Windows Runtime (WinRT) (Metro-приложения):This class and its members cannot be used in applications that execute in the Windows Runtime.
StackOverflow - MSDN: "This class and its members cannot be used in applications that execute in the Windows Runtime"
Wikipedia - Windows Runtime
Проблема там в другом. Я ещё раз взглянул на код. Ещё в первый раз меня кое что смутило, но я подумал, что так и должно быть...
Вы объявляете эти две переменных:
Код: Выделить всё
char PrinterName[120];
char BMPFileName[120];
Код: Выделить всё
if (!OpenPrinter(PrinterName, &hPrinterHandle, NULL))
Код: Выделить всё
FILE *BMPfile = fopen(BMPFileName, "r");
Код: Выделить всё
if (Image.Load(BMPFileName))

upd: ради интереса даже на XP проверил. В том виде, как есть, не работает. Если задать имя принтера и путь до bmp, то печатает. Правда почему-то делает выходную картинку аж 4672*6774 пикселя, видимо, надо покрутить какие-то параметры.
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Имя принтера и имя файла - внешние. Передаются через аргументы вызова функции из приложения.
Приведенные код - тело функции печати.
Она вызывается из главной функции DLL (в этом фрагменте ее нет).
Мне было бы проще сделать DLL на C#: там всего три строчки написать.
Но я не уверен, что механизм работы с памятью в .Net будет адекватен при работе DLL в среде LV.
И я не получу "нежданчики" в процессе длительной работы приложения на LV (периодических вызовов функции печати).
И вообще: если создавать DLL для среды LV, то какой язык программирования использовать?
Приведенные код - тело функции печати.
Она вызывается из главной функции DLL (в этом фрагменте ее нет).
Мне было бы проще сделать DLL на C#: там всего три строчки написать.
Но я не уверен, что механизм работы с памятью в .Net будет адекватен при работе DLL в среде LV.
И я не получу "нежданчики" в процессе длительной работы приложения на LV (периодических вызовов функции печати).
И вообще: если создавать DLL для среды LV, то какой язык программирования использовать?
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Решил задачу на низком уровне: написал три функции на С++ с использованием GDI и сделал DLL.
С C# рисковать не стал: слишком много версий .NET расплодилось.
Но с NI Report - отдельная проблема, блин.
С C# рисковать не стал: слишком много версий .NET расплодилось.
Но с NI Report - отдельная проблема, блин.
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Решил задачу на низком уровне: написал три функции на С++ с использованием WIN GDI и сделал DLL. Все поехало.
С C# рисковать не стал: слишком много версий .NET расплодилось.
Но с NI Report - отдельная проблема, блин.
С C# рисковать не стал: слишком много версий .NET расплодилось.
Но с NI Report - отдельная проблема, блин.
-
dadreamer
- professor
- Сообщения: 3962
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 13 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Некогда было этим заниматься, да и там, как оказалось, чуть больше времени потребовалось для переноса на БД. Кластеры, конечно, громоздкие, но с этим ничего не сделать. Можно оформить в SubVI, мне просто лень, два я сделал, на этом закончил.
, версии 2019, 2021 и 2023. Графика в *.bmp на форум не аттачится, картинки для проверки в MS Paint за пару секунд можно сделать. Пока успел проверить только на виртуальных принтерах: Adobe PDF, CutePDF Writer, doPDF 8 и Snagit 11/12. Любопытно, что у каждого принтера есть свои нюансы при печати, хотя по логике все должны отрабатывать задание одинаково. Например, CutePDF Writer не воспринимает пользовательские размеры листа, пока ему не задашь dmPaperSize = DMPAPER_USER. doPDF 8 почему-то картинку помещает справа и вертикально. Adobe PDF ухудшает изображения, впрочем этим и другие грешат, кроме Snagit.
Сейчас в примере печатается цветной файл. Как переключить на монохромный:
- в Connect Printer 2.vi задать dmColor=DMCOLOR_MONOCHROME;
- в кластере BITMAPV4HEADER основного
задать bV4BitCount=1, bV4ClrUsed=2, bV4ClrImportant=2;
- в CreateDIBitmap CLFN на вход pBitmapInfo завести розовый провод с присоединённой ч/б палитрой (после Bundle);
- на вход pArrayOfBytes завести массив image с Unbundle, а не с Unflatten Pixmap.
В принципе, это всё. Я проверял, тоже работает.
Кстати, у меня и DLL'ки тоже заработали после того, как я изменил пару мелочей:
- закомментил dm->dmDriverExtra = 0; (не всем принтерам нравится, когда dmDriverExtra заигнорен; например, Adobe PDF выдавал ошибку при StartDoc).
- прописал изменённые поля в dm->dmFields (не все поля структуры учитывались при печати).
Можно ещё по желанию прописать dmScale, dmPaperSize и dmOrientation.
Думал выложить скомпилированные файлы, но наверное это ни к чему. Всё-таки на диаграмме проще код поменять, если возникнет необходимость. Для компиляции нужна студия, нужно учитывать разрядность и т.п.
, выложенные выше. Насчёт .NET - думаю, правильное решение. Задача не самая сложная, тащить зависимость от фреймворка ни к чему. Хотя при инсталляции RTE он всё равно понадобится, но при явных зависимостях приложение будет дольше запускаться, станет тяжелее/прожорливее и может "тупить" временами, даже при корректно организованной архитектуре. Конечно, дотнет иногда необходим, если, например, используется какая-то сторонняя библиотека, от которой никуда не уйти. Но в большинстве случаев можно обойтись без него.
не сможете с ними работать. Чем проще, тем лучше. Массивы и строки передавайте по ссылке, остальное можно по значению. Кстати, и в обратную сторону (из LV в DLL) тоже не передавайте ничего
-специфичного, т.к.
хранит данные не так, как другие IDE (см. How LabVIEW Stores Data in Memory), это касается массивов и строк, а также ссылок (reference), путей, variant'ов. Если надо передать массив/строку, передайте указатель на данные. Указатели-параметры передавайте как Unsigned Pointer-sized Integer. В принципе, есть возможность работать с типами
из библиотеки при подключении extcode.h, но это довольно редко бывает нужно, современные версии
неплохо оптимизированы и выносить какой-то код во внешнюю библиотеку обычно не требуется.
Проверял как в 32-, так и в 64-битном 
Сейчас в примере печатается цветной файл. Как переключить на монохромный:
- в Connect Printer 2.vi задать dmColor=DMCOLOR_MONOCHROME;
- в кластере BITMAPV4HEADER основного

- в CreateDIBitmap CLFN на вход pBitmapInfo завести розовый провод с присоединённой ч/б палитрой (после Bundle);
- на вход pArrayOfBytes завести массив image с Unbundle, а не с Unflatten Pixmap.
В принципе, это всё. Я проверял, тоже работает.
Кстати, у меня и DLL'ки тоже заработали после того, как я изменил пару мелочей:
- закомментил dm->dmDriverExtra = 0; (не всем принтерам нравится, когда dmDriverExtra заигнорен; например, Adobe PDF выдавал ошибку при StartDoc).
- прописал изменённые поля в dm->dmFields (не все поля структуры учитывались при печати).
Можно ещё по желанию прописать dmScale, dmPaperSize и dmOrientation.
Думал выложить скомпилированные файлы, но наверное это ни к чему. Всё-таки на диаграмме проще код поменять, если возникнет необходимость. Для компиляции нужна студия, нужно учитывать разрядность и т.п.
Хорошо, что разобрались, можно тогда и на этом остановиться. В таком случае, возможно, кому-то ещё пригодятся

Вообще, в любой среде можете создавать, если она способна компилировать нативные DLL/SO. Просто не используйте в качестве аргументов и возвращаемого значения типы, специфические для среды (например, классы), сложные структуры, иначе в





-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
dadreamer, в твоем примере Print Test 3.vi используются функции из gdi32.dll.
Это будет корректно работать в LV x64 на платформе x64, или надо что-то заменять?
Наверняка у принтера драйвер установлен для целевой платформы, и если она x64, то и драйвер такой же.
Тут не будет конфликта?
Это будет корректно работать в LV x64 на платформе x64, или надо что-то заменять?
Наверняка у принтера драйвер установлен для целевой платформы, и если она x64, то и драйвер такой же.
Тут не будет конфликта?
-
dadreamer
- professor
- Сообщения: 3962
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 13 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Не будет и ничего менять не нужно. На 64-битной Windows системные библиотеки для 64-битных программ тянутся из \System32 и они там все 64-битные. Для 32-битных программ библиотеки тянутся из \SysWOW64, там лежат аналогичные версии библиотек, но 32-битные. Windows сама определяет, какие именно библиотеки нужны запускаемой программе. Циферка "32" в имени DLL - это по большей части для обратной совместимости, чтобы чужие приложения не поломались.PAG писал(а): ↑11 июн 2024, 11:41dadreamer, в твоем примере Print Test 3.vi используются функции из gdi32.dll.
Это будет корректно работать в LV x64 на платформе x64, или надо что-то заменять?
Наверняка у принтера драйвер установлен для целевой платформы, и если она x64, то и драйвер такой же.
Тут не будет конфликта?
Вчера я также пробовал запускать пример на Windows 10 64-bit и

-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
dadreamer, я сделал проектик на базе твоих примеров, который открывает принтер и подсовывает ему указанный битмапчик.
У меня битмапы монохромные, и принтер печатает их квадратами Малевича, т.е затушевывает всю картинку.
Подскажи, плз, что надо переключить в твоих модулях для монохромной картинки?
Примерчик изначально подразумевает полноцветную картинку, и заголовок сразу готовит для таких изображений.
Я подозреваю, что как минимум надо изменить некоторые поля в заголовке битмапа, или взять их из считанного заголовка, но боюсь накосячить. У меня картинки всегда монохромные.
У меня битмапы монохромные, и принтер печатает их квадратами Малевича, т.е затушевывает всю картинку.
Подскажи, плз, что надо переключить в твоих модулях для монохромной картинки?
Примерчик изначально подразумевает полноцветную картинку, и заголовок сразу готовит для таких изображений.
Я подозреваю, что как минимум надо изменить некоторые поля в заголовке битмапа, или взять их из считанного заголовка, но боюсь накосячить. У меня картинки всегда монохромные.
-
dadreamer
- professor
- Сообщения: 3962
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2024
- Благодарил (а): 13 раз
- Поблагодарили: 138 раз
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Попробуйте вот этот вариант.
- Вложения
-
- printer test 3.vi
- lv2019
- (20.48 КБ) 71 скачивание
-
- Connect Printer 2.vi
- lv2019
- (31.94 КБ) 70 скачиваний
-
- junior
- Сообщения: 66
- Зарегистрирован: 27 ноя 2020, 15:51
- Версия LabVIEW: 19
- Благодарил (а): 13 раз
- Поблагодарили: 3 раза
- Контактная информация:
Re: В какой среде (CPP/C#) может быть написана DLL, которую предполагается вызывть из среды LV?
Не помогло.
Я оказался не прав: картинка у меня была монохромная давно тому назад. Давно не лазил в эту процедуру, стал забывать.
Сейчас я отрисовываю ее на окне через Image с серой палитрой и записываю в файл через "Write BMP File.vi" (см. прицеп).
В результате получаю RGB файл с 8 бит на пиксел. Черная она только внешне.
Возможно, мне не стоит "ломать копья, и просто изменить формат создаваемого файла на полноцветный?
Но файл размером с печатный лист будет довольно большого размера. Это, конечно, пустяки, но как-то не очень хочется.
Прицепляю тестовую картинку и результат ее печати последней версией Вашей утилиты.
Возможно, будет проще изменить параметры создаваемой картинки в процедуре ее записи, изменив глубину цветности?

Сейчас я отрисовываю ее на окне через Image с серой палитрой и записываю в файл через "Write BMP File.vi" (см. прицеп).
В результате получаю RGB файл с 8 бит на пиксел. Черная она только внешне.
Возможно, мне не стоит "ломать копья, и просто изменить формат создаваемого файла на полноцветный?
Но файл размером с печатный лист будет довольно большого размера. Это, конечно, пустяки, но как-то не очень хочется.
Прицепляю тестовую картинку и результат ее печати последней версией Вашей утилиты.
Возможно, будет проще изменить параметры создаваемой картинки в процедуре ее записи, изменив глубину цветности?
- Вложения
-
- Результат печати
- Printer.png (2.51 КБ) 1611 просмотров
-
- процедура записи файла картинки
- WriteImage.png (5.83 КБ) 1611 просмотров
-
- Параметры файла картинки
- ImageParams.png (10.24 КБ) 1611 просмотров
-
- Тестовая картинка (реально *.bmp)
- Report.png (930 байт) 1590 просмотров
Последний раз редактировалось PAG 21 июн 2024, 15:32, всего редактировалось 3 раза.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение