Перейти к публикации

NX10 не пишет в консоль


void

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

Коллеги, добрый день!


 


Проект из 10й студии (под NX8) перекомпилирован в 12й под NX10. Отрабатывает до конца, но не пишет в консоль ни printf, ни cout, ни wprintf. Консоль загружается, но пустая.


Проект консоли тоже перекомпилирован под NX10.


 


Причем если в NX10 запустить dll, скомпиленную для NX8, то в консоль идет печать.


 


Подскажите, пожалуйста, в чем может быть дело.


Без консоли как-то некомфортно.


 


Заранее спасибо!


Ссылка на сообщение
Поделиться на других сайтах


UG/Open и т.д. очень давно не трогал.

 

Может поэтому не совсем понял.

Что за отдельный проект консоли?

У Вас две отдельные dll?

Или один проект в виде внутренней dll, а другой проект external exe (который и создаёт свою консоль)?

Что возвращают функции типа GetConsoleTitle, GetConsoleWindow и подобные в случае когда в консоль ничего не пишется?

 

P.S.: Разница может быть в библиотеках (и типах библиотек в настройках) C/C++ студии, которые линкуются с проектом в том или ином случае, или ещё в каких-то настройках. Не понял как у Вы в проекте к консоли приаттачиваетесь, поэтому и уточняю.

Ссылка на сообщение
Поделиться на других сайтах

Обычно консоль грузится в ufsta() на старт NX, а из своих dll просто printf() и т.п. 

Перекомпилировал под NX10 в 12-й студии проект консоли - всё работает.

 

Т.е. как я понял, старые dll печатают и в новую консоль, а новые (из 2012 студии) нет?

Изменено пользователем harbel
Ссылка на сообщение
Поделиться на других сайтах

Коллеги, спасибо за ответы!

Да, все так, консоль перекомпилирована, лежит в ufsta().

Консоль загружается.

При запуске старые (не перекомпилированные в 12й студии) dll печатают в консоли. А новые (перекомпилированные в 12й) не печатают. Пустое черное окно.

 

Раз так, с консолью все нормально, видимо.

 

Вот что может быть с проектом в 12й студии? Может, действительно, какие-то настройки?.. Вроде все идентично...

 

Заранее спасибо.

Ссылка на сообщение
Поделиться на других сайтах
void, а как Вы проект переносили c 10-й на 12-ю?

 

Так dll-ка то итоговая одна?

Или две?

Одна отрабатывает на старте, создавая консоль, а затем вторая уже работает с консолью?

Но при этом всё в рамках одного процесса ugraf.exe?

 

Как вариант - использовать в проекте функции, которые служебную инфу по консоли собирают, и скидывать во время выполнения функции dll инфу в файл на диске.

 

Посмотрите какой вариант линковки со стандартной C/C++ библиотекой. В обоих случаях один и тот же тип? Например статическая многопоточная?

 

А стандартную точку входа в DLL 12-й версии не меняли? Я не про пользовательские типа ufsta,  ufusr (или как её там). а про ту, которая обычно DLLMain.

 

Вариантов то много.

 

Например неправильно прошла инициализация стандартной библиотеки, или стандартные потоки ввода-вывода не связаны по какой-то причине с нужной консолью.

Изменено пользователем Ленивый
Ссылка на сообщение
Поделиться на других сайтах

Проект уже и конвертацией переносили. 

И заново пересобрали. С NX10 wizard'ом

 

Две dll. Одна создает консоль, лежит в ufsta.

Вторая печатает в консоль. Точка входа ufusr.

 

GetConsoleTitle возвращает путь ugraf.exe

GetConsoleWindow возвращает хендлер

 

Но WriteConsole не пишет.

Ссылка на сообщение
Поделиться на других сайтах

В обоих случаях GetConsoleTitle возвращает одну и ту же строку?

 

По параметрам в приложенных скриншотах между 10-й и 12-й различий нет (скриншоты из VS 2015 Community)?

 

Как вариант могу ещё предложить временно перенаправить поток вывода stdout по мотивам

http://www.realcoding.net/articles/perenapravlenie-stdout-v-oblast-pamyati-ili-fail.html

или

https://msdn.microsoft.com/library/wk2h68td%28v=vs.110%29.aspx

или

http://ipg.h1.ru/lessons/ci/les89.html

или

http://forums.codeguru.com/showthread.php?379388-Standard-output-device&p=1350306#post1350306

 

Или вот здесь была какая-то проблема http://www.cyberforum.ru/cpp-beginners/thread343360.html

 

Вот ещё: https://support.microsoft.com/en-us/kb/105305

 

В общем чем-нибудь типа freopen направить поток stdout в какой-нибудь файл.

И посмотреть будет ли printf писать в файл.

Если и в файл записи не будет, то тогда чего-то не так со стандартной библиотекой.

А если будет, то чего-то не так со связью с консолью.

 

Как именно создаёте консоль?

Какой функцией?

Код (точнее его кусок) в студию! :-)

 

 

 

post-33928-0-68872600-1454508752.png

post-33928-0-89380500-1454508756.png

Ссылка на сообщение
Поделиться на других сайтах
	GetConsoleTitle(buffer, 256);

	HWND hw = GetConsoleWindow();
	
	SetConsoleTitle(L"Test");
	
	LPTSTR b = L"qwerrtyrweuewrweryeuioyerio";

	HANDLE newBuf = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
	SetConsoleActiveScreenBuffer(newBuf);

	WriteConsole(newBuf, b, lstrlen(b), lp, NULL);
	
	char *s = "\njksdhf311111111111111455";
	WriteConsole(newBuf, A2W(s), lstrlen(A2W(s)), lp, NULL);

Коллега, спасибо за понимание! Получилось вот так: создать новый буфер консоли и туда писать. 

Хоть что-то, как вариант. Но в целом не айс. 

Странно, что не пишет в буфер косоли, который по умолчанию.

 

Дело в том, что туда пишет dll, откомпилированная в 10 студии. Значит с консолью все в порядке.

Стандартные функции пишут в файл.

Но dll, откомпилированная в 12 студии, пишет в консоль только в новый буфер.

Ссылка на сообщение
Поделиться на других сайтах

Да не за что, только результата то ещё нет пока что. :-)

 

Ещё раз дам ссылку: https://support.microsoft.com/en-us/kb/105305

Самое главное здесь - это раздел MORE INFORMATION, в нём самая мякоть.

 

И ещё я приводил ссылку: http://www.cyberforum.ru/cpp-beginners/thread343360.html

Там человеку помог этот метод из статьи.

int hCrt;
FILE *hf;
hCrt = _open_osfhandle(
             (long) GetStdHandle(STD_OUTPUT_HANDLE),
             _O_TEXT
          );
   hf = _fdopen( hCrt, "w" );
   *stdout = *hf;
   i = setvbuf( stdout, NULL, _IONBF, 0 );

Цитата из той статьи:

When a GUI application is started with the "start" command, the three standard OS handles STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all "zeroed out" by the console initialization routines. These three handles are replaced by valid values when the GUI application calls AllocConsole(). Therefore, once this is done, calling GetStdHandle() will always return valid handle values. The problem is that the CRT has already completed initialization before your application gets a chance to call AllocConsole(); the three low I/O handles 0, 1, and 2 have already been set up to use the original zeroed out OS handles, so all CRT I/O is sent to invalid OS handles and CRT output does not appear in the console. Use the workaround described above to eliminate this problem.

 

 

 

Когда GUI приложение (в нашем случае - NX) запускается командой "start" (запускается стандартно через Пуск или даблкликом по ярлыку) три стандартных системных хэндла STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE обнулены процедурой инициализации консоли. Потом эти три хэндла получают валидные значения, когда GUI приложение (NX)  вызывает функцию AllocConsole(). И после этого вызов GetStdHandle() будет возвращать эти корректные значения. Вот только проблема в том, что CRT (стандартная библиотека C++, в которой реализуются printf и т.д.) инициализируется ещё до того, как у вашего приложения будет шанс вызвать AllocConsole(), и инициализируется она неправильно, обнуленными значениями, поэтому все вызовы функций ввода-вывода из CRT будут работать с неправильными внутренними переменными библиотеки CRT. Используйте обходной путь, описанный выше.

 

Другими словами:

1) NX запускается.

2) Системные хэндлы  STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE обнуляются (т.к. NX - GUI приложение, а не console).

3) CRT C++ свои внутренние переменные  FILE* stdout, FILE* stdin, FILE* stderr инициализирует на основе текущих значений системных хэндлов, а значит на основе неправильных значений, а значит внутренние переменные CRT тоже получат НЕПРАВИЛЬНЫЕ значения.

4) Ваша dll вызывает AllocConsole(), системные хэндлы STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE получают правильные значения.

5) Вот только внутренним переменным CRT С++ FILE* stdout, FILE* stdin, FILE* stderr уже это безразлично, они сдохли и остывают, а стартовый код CRT уже отработал, и правильно их не инициализирует.

6) Возможный правильный выход из такой ситуации - после вызова AllocConsole() вручную проинициализировать внутренние переменные CRT C++, т.е. проделать ту работу, что выполняет стартовый код CRT.

 

Ниже приведу возможную причину странного поведения:

Почему в случае когда обе DLL на 12-й, то не происходит записи в консоль?

Да потому что вполне может быть так, что они обе пользуются одной и той же CRT, в которой уже всё сдохло!

Почему в варианте 10 + 12 запись работает?

Да потому что они пользуются разными CRT, и одной код инициализации работет ДО AllocConsole, а у другой ПОСЛЕ (а значит внутренние переменные получают значения на основе верных значений системных хэндлов)!

Но это гипотеза и её надо проверять, потому я могу быть десять раз неправ.

 

А почему всё работало раньше в NX8?

Тут тоже есть гипотезы (завязанные на CRT), но проверьте сначала то что я написал выше.

Про WriteConsole пока не надо, у меня в своё время она глючила (доверия к ней нет, хотя и вариант кривых рук не исключаю, ага), причину так и не установил, да и вы не показали как вы её вызывали в самом первом случае, когда написали, что она не пишет.

Да и про настройки подключения стандартной библиотеки вы ничего не сказали.

Изменено пользователем Ленивый
Ссылка на сообщение
Поделиться на других сайтах

Понял, что мог мог частично бред написать, т.к. не знал, что _DllMainCRTStartup в любом случае линкуется статически, но все равно попробуйте.

Ссылка на сообщение
Поделиться на других сайтах

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

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

Гость
Ответить в тему...

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

  Разрешено не более 75 эмодзи.

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

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

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

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.




  • Сообщения

    • Krusnik
      Да тут постоянно, по-моему об этом пишут. Такие как вы уже всех заколебали. Поэтому такие и ответы. Но специально для вас распишу все отличия.    1) Графика RealView. С игровой видеокартой она просто в SW отключена. С профессиональной включается. Нужна для показа на мониторе красивых картинок в 3D. Скажем руководству, или заказчикам. Ну и потом. Вы купили SW, а часть функций, за которые выплаченна немалая сумма не доступна. Что за фигня?   2) При вращении и/или масштабировании сборок с игровой видеокартой модели во время манипуляций превращаются в BoundingBox'ы, а когда отпускаешь мышку - отрисовываются. Зависит это от количества графических треугольников, которые нужно отрисовать. Т.е. с небольшими и простыми модельками не заметите, со сборками хотя бы от 300 деталей - будет заметно. Многие советуют понижать детальность, но тут тоже такое себе удовольствие, когда круглое отверстие превращается в восьмигранник, и только из-эт того, что кто-то решил, что для SW 4080 круче, чем A4000. У меня на сборках 8000 деталей и Quadro так делает, но игровые так начинали с примерно 300 деталей.
    • maxx2000
      а если делать канавку снаружи на глубину чуть больше толщины кольца, а потом изнутри растачивать и кольца будут повисать прямо на резце. Собственно по такому принципу и режутся кольца на универсальном токарном, нарезают канавок, а потом сверлом вжик и готово
    • Orchestra2603
      Да, в рот мне ноги... Ну, считает же Ансис, считает! Блин.. Как до вас донести простой мэсеж. Мне често, пофигу, делает он там себе факторизацию или еще что-то. Но то, что он нормально считает Ланцошем для случая с вырожденной матрицей жесткости - это факт! А раз он считает, то либо (А) вы хрень несете про факторизацию, либо (Б) он такую факторизацию делат сам без проблем. Третьего тут быть не может, и выходит, что в любом случае ваши тезисы оказываются несостоятельными.   Какая вам нужна факторизация? давайте! заказывайте! На какие вам надо матрицы разложить? с какими свойствами? давайте ваш заказ!   Вы на мой пердак не зарьтесь! Смотрите, чтоб ваш функционировал исправно! А то того и гляди, фекализация случится.  
    • Иван Васильев
      Доброго времени суток! Удалось решить проблему?
    • ДОБРЯК
      Вам похоже ничего не нужно, а для алгоритму Ланцоша нужно сделать численную факторизацию. Вам только нужно побольше букв и слов написать. :=) Всё подгорел пердак? :=)
    • Orchestra2603
      При чем здесь это? Речь не идет про эффективные или неэффективнеы алгоритмы. Вы утвержаете, что это просто невозможно.   При чем здесь первые или не первые, все или не все... Какое это имеет значение? У Ансис есть алгоритм Ланцоша, он находит столько, сколько запросите. В Маткаде - он да, находит все. Наверное, можно и не все, но я хз, как это делать. Я не понимаю, какое это имеет отношение к разговору.   Неа Ткните пальцем и объясните, в чем ошибка в конкретном рассуждении   Как я должен решать методом Гаусса задачу на собственные значения? Мне же не решения СЛАУ нужны! Их то, ясен пень, бесконечное множество для системы с вырожденной матрицей. Мне собственные значения нужны! Мне нужно базис найти, чтобы матрица (или матрицы в обобщенном случае) оператора была диагональной.   Сначала скажаите мне, зачем ее дать! В чем идея заключается? Вы все слюной брызжете, но ничего по делу еще не сказали. Какой-то нормальный контраргумент от вас можно толковый услышать?   Как еще изволите вас обслужить? Вы - полегче, уважаемый!
    • ДОБРЯК
      Вам нужно десять раз написать одно и тоже, чтобы вы поняли. Почитайте документацию к программе там же всё написано. Мне не сложно копировать...:=) Те алгоритмы которые вы используете находят все собственные числа и вектора. Для разреженных матриц это приводит к их заполняемости. Смекаете о чем я говорю. Или нужно еще разжевать? Во всех.   Решайте методом Гаусса. Матрица 2х2 в чем проблема сделать численную факторизацию любым методом? :=) Больше дела, меньше слов и букв...
    • mannul
      Скорость резания от 8 до 12 м/мин, подача 0,04 мм/зуб, глубина резания - 1,5 мм.
    • Orchestra2603
      " Стою на асфальте я, в лыжи обутый: То ли лыжи не едут, то ли я ..." (с)   1. Вы утверждаете, что для расчетов на СЗ и СВ в случае вырожденной матрицы жесткости нужно провести ее факторизацию. Без нее - никак! Непонятно, какую и зачем, но надо. Ок, допустим.  2. @Jesse,  я, @Fedor, да и вы сами показываете, что таки СЗ определяются для вырожденной матрицы. Значит, либо ваше утверждение про факторизацию неверно, либо она таки делается тихонько себе за кадром. 3. Еще одно наблюдение... Матлаб говорит, что он делает QZ разложение для матриц, у которых нет положительной определенности, т.е. для которых не работает разложение Холецкого. При этом опять же с собственные числа с одной вырожденной матрицей считаются нормально. Т.е. даже если вдруг и необходима такая факторизация (хотя я сомневаюсь, что вот прям обязательно она нужна), то делается она без особых трудностей.   В каком месте я неверно рассуждаю?   Так и не обязательно их записывать для расчета собственных колебаний. Ну... Можно конечно, но тогде некоторые частоты и формы, которые такой симметрией могут и не обладать, вы потеряете в расчете, поскольку введенные условия симметрии их исключат просто из модели.    
    • gudstartup
×
×
  • Создать...