Страницы

Поиск по вопросам

вторник, 12 февраля 2019 г.

Подключение bitbucket к visual studio

Как подключить существующий репозиторий с bitbucket к проекту в visual studio, и управлять изменениями из студии?


Ответ

Заходите в репозиторий на Битбакете, в меню слева кликаете на Clone, выбираете HTTP и копируете ссылку (аналогично и для Гитхаба/Гитлаба/любого другого репозитория -- нужна http ссылка на репозиторий):

Затем в Team Explorer выбираете создание нового репозитория:

В разделе Local Git Repositories выбираете Clone, указываете ссылку на репозиторий и куда клонировать:

Готово.

Нажатие стрелок С++

Решил написать консольного Марио и столкнулся с такой проблемой: как отлавливать событие нажатия стрелок на клавиатуре, скажем через WinApi или при помощи стандартных средств с++? (Windows)
void Game::input() { Key key; char c; while (true) { cin >> c; switch (c) { case up_key: movePlayer(player_pos + new Position(0, -3)); break; case down_key: movePlayer(player_pos + new Position(0, 1)); break; case right_key: movePlayer(player_pos + new Position(1, 0)); break; case left_key: movePlayer(player_pos - new Position(1, 0)); break; } show(); } }


Ответ

Ну, в консоли Windows можно воспользоваться не входящей в стандарт, но входящей в SDK getch()
#include #include
int main(int argc, const char * argv[]) { int k1, k2; for(;;) { k1 = _getch(); if (k1 == 0xE0 || k1 == 0x00) { k2 = _getch(); switch(k2) { case 0x4B: printf("Left on %s kbd
", k1 ? "main" : "extended"); break; case 0x48: printf("Up on %s kbd
", k1 ? "main" : "extended"); break; case 0x4D: printf("Right on %s kbd
", k1 ? "main" : "extended"); break; case 0x50: printf("Down on %s kbd
", k1 ? "main" : "extended"); break; } } } }

Как исправить код, чтобы не было 'String index to var param'?

Function exchange(input: String): String; Var I: Integer; Begin Result:=input; I:=Length(Result); For I:=1 To I Do Begin If Result[I]='a' Then Result[I]:='b'; //[DCC Error] test.pas(13): E1047 Unsafe code 'String index to var param' If Result[I]='c' Then Result[I]:='d'; //[DCC Error] test.pas(14): E1047 Unsafe code 'String index to var param' If Result[I]='e' Then Result[I]:='f'; //[DCC Error] test.pas(15): E1047 Unsafe code 'String index to var param' End; End;
Именно изменить, что можно отключить предупреждения я знаю, мне интересно как же пишется этот "надёжный" код и что именно ему тут не нравится?


Ответ

Вот такой код будет корректным и безошибочным:
Function exchange(input: String): String; Var I: Integer; sb: TStringBuilder; Begin sb := TStringBuilder.Create(input); try For I := 0 To sb.Length - 1 Do Begin if sb.Chars[I] = 'a' Then sb.Chars[I] := 'b'; if sb.Chars[I] = 'c' Then sb.Chars[I] := 'd'; if sb.Chars[I] = 'e' Then sb.Chars[I] := 'f'; End; Result := sb.ToString; finally sb.Free; end; End;
А теперь объяснение:
В современных версиях Делфы, при внедрении поддержки новых платформ (iOS, Android, x64 и т.п.) было принято решение уходить от строк индексируемых 1 .. N в пользу стандартных с индексацией 0 .. N-1. Данное изменение ломает практически весь существующий код. Поэтому его внедрение идет очень медленно и постепенно. В какой-то версии добавили предупреждения, в какой-то {$IFDEF ZEROBASEDSTRINGS}. Где-то эта директива включена по умолчанию, но в основном нет.
О чем говорит данное предупреждение - о том, что обращаться к строкам по индексу небезопасно, т.к. индексация может быть заранее неизвестна (в зависимости от директивы и целевой платформы).
Как быть?
Самое простое решение, если вам нужна только Win32 - отключить предупреждения и спокойно жить дальше. Самое правильное, если вам нужны новые платформы - переписать код с использованием построителя строк (TStringBuilder), который сам разберется как именно строка индексируется, и предоставляет к ней единый интерфейс через свои методы.
P.S. Как ни странно, For I:=1 To I Do является вполне корректным кодом, т.к. цикл сохраняет максимальное значение до начала итерирования.

какую модель памяти сегментную или страничную использует windows, linux, macos?

При прочтении Таненбаума возникли сложности с пониманием организации памяти в ОС. Какая модель используется в современных ОС? Сегментная, страничная, сегментно-страничная? В частности привело смущение сказанное про компиляторы, что для них использование сегментной организации памяти гораздо удобнее, но компилятор же запускается в ОС. Это и запутало. Как я понимаю как работать с памятью реализовано в ОС, но разве программа может изменить этот способ?


Ответ

В современных ОС используется либо страничная, либо сегментно-страничная организация памяти. Сегментная не выгодна с точки зрения рациональности использования физической памяти (возможна фрагментация).
За всю работу по переводу логического адреса в физический ответственна аппаратура ( MMU ), а за формирование правил и таблиц по которым будет осуществлен перевод - ОС.
То есть, компилятор (и любая другая программа) не может перейти в другой режим адресования.
С точки зрения прикладной программы, она (программа) находится в линейном адресном пространстве размером около 2Гб (для 32 битной windows), так как, 2 ГБ виртуального адресного пространства занимает код ОС, драйверов и DLL.
Хочу заметить, что виртуальный адрес не имеет ничего общего с физическим
Очень утрированно процесс управления памятью показан на картинке ниже:

Как узнать и поменять владельца файла?

Написал код, который чудесно узнает текущего владельца файла, но никак не хочет его менять на какого-либо другого. Судя по MSDN, все прописано так, как надо. Но не работает.
Вот код:
using System; using System.IO; using System.Security.Principal;
namespace GET_SET_OWNER { class Program { public static bool GetOwner(string File_UNC) { Console.WriteLine("Текущий владелец:"); var File_Security = File.GetAccessControl(File_UNC); var SID = File_Security.GetOwner(typeof(SecurityIdentifier)); Console.WriteLine(SID);
var Owner = SID.Translate(typeof(NTAccount)); Console.WriteLine(Owner); return true; }
public static bool SetOwner(string File_UNC) { Console.WriteLine(Environment.NewLine + "Задаем нового владельца..." + Environment.NewLine); var New_Owner = new NTAccount("Home", "Браток"); var File_Security = File.GetAccessControl(File_UNC); File_Security.SetOwner(New_Owner);
try { File.SetAccessControl(File_UNC, File_Security); } catch (InvalidOperationException) { return false; } return true; }
static void Main(string[] args) { const string File_UNC = @"D:\1.txt"; bool res_1 = false, res_2 = false, res_3 = false;
res_1 = GetOwner(File_UNC); res_2 = SetOwner(File_UNC); res_3 = GetOwner(File_UNC); Console.WriteLine("{0} {1} {2}", res_1, res_2, res_3); Console.ReadLine(); } } }
Есть у кого-нибудь идеи? Функция SetOwner при каждой попытке изменить текущего владельца выдает System.InvalidOperationException: Идентификатору безопасности запрещено быть владельцем данного объекта и возвращает false. При этом, если менять владельца файла на текущего, то есть, например,(Пользователь) - это текущий владелец, меняем на (Пользователь), то функция проделывает свою работу и возвращает true
В случае, когда текущий владелец файла Браток, программа справляется с задачей и меняет владельца на любого другого в системе. То есть сменить владельца с Браток на Пользователь - это не проблема. Проблема в том, чтобы провести операцию по смене владельца с Пользователь на Браток


Ответ

Хорошие вопросы редкость.
Проблема вот в чем. Для того чтобы стать владельцем объекта файловой системы, пользователь должен иметь право становиться владельцем либо быть администратором. Если условия выполнены - пользователь может назначать себя и только себя владельцем объекта ФС.
Для того чтобы назначить владельцем другого пользователя - нужны права на восстановление объектов ФС. По умолчанию эти права отключены даже для администратора. Собственно поэтому у вас и получается переназначить владельца на себя и не получается наоборот.
Собственно решение проблемы - назначить процессу или пользователю, от чьего имени запускается процесс, права на восстановление объектов ФС.
В сети на эту тему информация 5-7 летней давности, но похоже что до сих пор ни чего не поменялось и .NET не предоставляет средств для получения этих прав, но можно воспользоваться средствами WinAPI. Одно из таких решений на которое часто ссылаются можно посмотреть в блоге salamandersoft а также в ответе @VladD тут

Как удалить локальную ссылку на несуществующую уже удаленую ветку?

В локальном репозитории вижу следующую картину:
| | * origin/ |
На сервере (битбакет) этой ветки уже нет и давно.
git push origin :
логично выдает
remote ref doesn't exist
Как мне удалить локальную ссылку на несуществующую уже удаленную ветку?


Ответ

Нужно выполнить команду git fetch с флагом prune.
git fetch --prune
Если удаленных репозиториев несколько, можно указать конкретный:
git fetch origin --prune
То же самое:
git remote prune origin
Это удалит референсы на ветки удаленного репозитория, которых больше не существует.
При этом у вас могут еще остаться локальные ветки с которыми вы работали и которые раньше ссылались на несуществующие ветки удаленного репо.
Эти ветки надо поудалять ручками с помощью:
git branch -d

Поддерживает ли SslStream (или сам LSASS) TLS compression?

Поддерживает ли SslStream (или сам LSASS) TLS compression? Если да - то какими опциями рееста\настройками ОС\вызовами из кода можно манипулировать (включать\отключать) сжатием?


Ответ

Скажу коротко:
Нет
SslStream в сочетании с протоколом TLS 1.2 поддерживает только null compression. Попробуйте отослать запрос из SslStream и посмотреть, какие есть "Compression Methods" при Client Hello, там будет только Comperssion Method: null.
Сжатие данных в TLS не поддерживается во многих современных библиотеках, да и не только в .NET, потому что его поддержка лишена смысла из-за аспектов безопасности и здравых соображений. Да, это помогает медленным каналам, но здесь появляется уязвимость..
Стандарт TLS 1.3, который сейчас находится в стадии "черновика" предусматривает удаление такого понятие как сжатие данных.
Все это связано с тем, что появилась различные атаки на SSL/TLS при использовании сжатия, одна из них называется CRIME (Compression Ratio Info-leak Made Easy), хотя есть еще BREACH (Browser Reconnaissance & Exfiltration via Adaptive Compression of Hypertext)
Алгоритм атаки
Если говорить кратко, то атакующий должен использовать сначала первичную атаку «Man In The Middle» (MITM), т.е Хакер должен перехватывать весь пользовательский трафик, неважно как, пусть даже разрезав ваш кабель и подсоединив его к своему компьютеру.
Добавляя в него свои данные, он отправляет запросы на сервер. Алгоритм сжатия в силу своих особенностей, при повторении части текста естественно сжимает его.
После отправки данных на сервер, хакер смотрит за длиной сообщения и если оно уменьшилось, значит подобрана правильная последовательность. Тем самым можно подбирать отдельные строки и параметры в запросе, например, значения куки. Но есть ограничения — часть данных нужно знать, чтобы от неё начать подбирать остальную информацию.
В атаке не взламывается шифр, не подбирается ключ шифрования, а подбираются значения зашифрованного текста.

Как узнать валюту страны, в которой находится пользователь?

Как можно узнать валюту той страны, в которой на данный момент находится пользователь Android-приложения? Предполагается, что пользователь часто путешествует и меняет страну. Подскажите какой-нибудь сервис с открытым API.


Ответ

Решение с конца: https://developer.android.com/reference/java/util/Currency.html Класс который отдает код валюты, символ и т.п. Делается из локали:
Currency currency = Currency.getInstance(locale);
Локаль можно сделать из координат:
Geocoder geocoder = new Geocoder(ctx, Locale.getDefault()); List

addresses = geocoder.getFromLocation(latitude, longitude, 1); if (addresses.size() > 0) { Address address = addresses.get(0); regionCode = address.getCountryCode(); }
Статья от первоисточника: https://developer.android.com/training/location/display-address.html
regionCode должен содержать 2х символьный код, например 'RU','US','DE'.
Из этого кода и делаем локаль:
Locale whereMI = new Locale(regionCode);
Мои извинения за бессвязность кода, надрал из разных проектов по частям.
П.С. Еще вместо GPS для получения кода страны можно использовать ip-api.com/json . С известными оговорками конечно.

Множественное наследование Интерфейсов

Допустим, два интерфейса, Alpha и Beta, реализуются в классе MyClass
Что, если в обоих этих интерфейсах предоставляется метод reset(), объявляемый ­по умолчанию? Какой из вариантов этого метода будет выбран в классе MyClass? Из интерфейса Alpha или Beta?
С другой стороны, рассмотрим ситуацию, когда интерфейс Beta расширяет интерфейс Alpha.
Какой вариант метода по умолчанию используется в этом случае? А что, если в классе MyClass предоставляется собственная реализация этого метода?
Вопрос: приоритет отдается реализации метода в классе над его реализацией в интерфейсе. Как это понять?


Ответ

Какой из вариантов этого метода будет выбран в классе MyClass?
Никакой. Будет ошибка на этапе компиляции.
С другой стороны, рассмотрим ситуацию, когда интерфейс Beta расширяет интерфейс Alpha
В этом случае будет вызван метод из Beta
А что, если в классе MyClass предоставляется собственная реализация этого метода?
Тогда будет использоваться реализация метода из самого класса.
Вопрос: приоритет отдается реализации метода в классе над его реализацией в интерфейсе. Как это понять?
Если в интерфейса есть реализация метода по умолчанию, а в классе (который реализует этот интерфейс) этот метод тоже есть, то будет вызван метод из класса.
Собственно, утверждение из Вашего четвертого вопроса – это ответ на третий.

Автоматический ежедневный коммит в репозиторий git

Как реализовать автоматический коммит и пуш в удаленный репозиторий используя базовые утилиты Ubuntu? Как корректно обработать отсутствие изменений? Данный репозиторий планируется использовать для архивного хранения изменений на сайте без cms.
У нас уже нормально используется git для хранения кода, но вот сейчас задумались о том, чтобы хранить сайт без cms в git. Это даже скорее архивное хранение. Ну и "отчетность" о том, что и когда меняли


Ответ

По моему личному мнению, всё нужно делать ровно наоборот.
Вы меняете сайт напрямую и хотите сохранять изменения постфактум.
В результате у вас будет только информация о том, в какой день изменилась та или иная строка, но никакой информации о точном времени и авторе изменения. А когда нет информации об авторе, нет и ответственности. А ещё изменения, внесённые в течение дня, не будут иметь бэкапа. Изменения также не будут иметь осмысленного комментария. Зачем что-то поменяли или добавили? Через неделю уже никто не вспомнит.
Считайте, что вы купите абонемент на факапы. Другими словами, технически ваша задача решается очень легко (cron + git), но эта задача не приблизит вас к цели - бэкапам и отчетности об изменениях.
Гораздо более надёжный способ - проводить все изменения сразу и исключительно через git, разворачивая боевое окружение из определённой ветки (обычно master или production). Способов разворачивать сайт из git множество и они за рамками этого вопроса.
Суть вот в чём: если кто-то захотел поменять хоть даже одну строку - делает коммит в ветку, из которой разворачивается сайт. Если этот коммит всё сломал - откатываемся на прошлый и делаем выводы.
Очень хорошо и надёжно будет использовать тестовое окружение, чтобы не выкатывать сразу на бой. В таком случае вы либо разворачиваете сайт на тестовое окружение из каждой feature-ветки, или из какой-то одной, в которую мержатся feature-ветки. Довольно распространённая практика: master разворачивается на stage, production разворачивается на бой.
Про развертывание сайтов из git:
Не самые современные методы: Настройка и развертывание проекта c помощью Git Вполне современный метод: (Habr) GitLab CI: Учимся деплоить Using Git to manage a web site How To Set Up Automatic Deployment with Git with a VPS
Про модель работы и релизы (каждое изменение на бою - это релиз, хоть и небольшой)
Как правильно отправить релиз на git?

Логика и назначение Product trait

Столкнулся с проблемой непонимания как работает trait Product. Пример:
List(1,2).productIterator.toList
Возвращает
List[Any] = List(1, List(2))
Покопавшись в документации пока не смог найти ответа на вопрос почему 2-ой элемент возвращается как List(2) а не просто 2. Спасибо.


Ответ

Для начала объясню что такое List, потом объясню как работает productIterator
И так List - это абстрактный класс, а значит создать его экземпляр нельзя. То что выглядит как List - на самом деле один из его наследников. У класса List два наследника - кейс-класс :: и кейс-объект Nil
Давай посмотрим на их реализацию:
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] { override def tail : List[B] = tl override def isEmpty: Boolean = false }
case object Nil extends List[Nothing] { override def isEmpty = true override def head: Nothing = throw new NoSuchElementException("head of empty list") override def tail: List[Nothing] = throw new UnsupportedOperationException("tail of empty list") // Removal of equals method here might lead to an infinite recursion similar to IntMap.equals. override def equals(that: Any) = that match { case that1: scala.collection.GenSeq[_] => that1.isEmpty case _ => false } }
То, что Nil - это пустой список, знают многие, поэтому рассмотрим кейс-класс ::. Как видишь у него два поля - head и tl. Заметь что head- это один элемент, а tl - коллекция(List). Т.е. когда мы пишем
List(1)
на самом деле создается такой кейс-класс:
::(1, Nil) ::(head = 1, tl = Nil)//тоже самое с именованными параметрами
А когда ты создаешь List(1, 2) на самом деле создается такое:
::(1, ::(2, Nil))
::(head = 1, tl = ::(2, Nil)) //тоже самое с именованными параметрами
Обрати внимание на то, что второй параметр имеет тип List, а значит какого бы ты наследника не передал (:: или Nil) - виден он будет как List
Теперь про productIterator, этот метод возвращает итератор на аргументы класса. В нашем случае у объекта Nil - нету аргументов, а у класса :: есть всего два аргумента - head и tl. Их значения ты и видишь.
P.S. А метод productIterator у них есть - благодаря тому, что они кейс-класс и кейс-объект.
Полезные материалы:
http://www.alessandrolacava.com/blog/scala-case-classes-in-depth/ http://www.scala-lang.org/api/current/scala/collection/immutable/List.html исходники Scala

Как тестировать объекты со сцены юнити?

Все юнит тесты обычно находятся в папке Editor и не наследуют от MonoBehaviour. Как протестировать элемент со сцены в юнит тесте или проще говоря как добавить элемент сцены в юнит тест? P.S. Как я понимаю искать элементы с помощью Find, FindGameObjectWithTag и т.д. не совсем правильно.


Ответ

Один из способов, как мне кажется, это просто создать новый пустой объект в тестируемом методе, добавив нужный компонент или инстанциировать нужный префаб и запустить тест? Пример:
GameObject go = new GameObject(); go.AddComponent();
// do smth...

Но...

Unity Test Tools - пакет, с помощью которого можно протестировать объекты на сцене.
Например к объекту прикрепляется компонент Assertion Component (он есессн будет Monobehaviour):

В нём можно задать любые параметры, которые душе угодно: объект тестирования, параметры тестировани, с чем сравнивать, сколько должен длиться тест, в какой момент времени проверять (Start, Update, OnTriggerEnter и прочее) и многое другое.
Документацию о нем можно почитать их доки:
bitbucket.org/Unity-Technologies/unitytesttools/wiki/Home
Ознакомиться можно также посмотрев небольшое видео в обучающих материалах на самом сайте Unity:
https://unity3d.com/ru/learn/tutorials/topics/production/unity-test-tools.
Там описан пример как с Unit test так и Integration test

Наполнения списка возможных Command Arguments

Есть ли возможность для *.vcxproj указать перечень возможных аргументов для запуска приложения?
Цель: вбить 3-4 варианта запуска приложения с определённым набором аргументов и выбирать их с выпадающего списка Command Arguments в настройках проекта в вкладке Debugging
Сейчас приходится руками каждый раз писать "переключение":
iPhone iPhone7 fullscreen и т.д.


Ответ

Есть расширение для Visual Studio Set Project Command Line Arguments 2015 . Судя по описанию, как раз то, что требуется:
For example you can create a text file containing commonly used command arguments and then position your cursor on the line you want and this command will copy that line of text into the startup project's command line arguments property

Приведение типа в списках инициализации, как лучше?

У меня в классе есть поле std::uint64_t m_value. В конструкторе по умолчанию я пишу в списке инициализации : m_value(0). Работаю с разными компиляторами, при этом можно в настройках проекта отрегулировать вывод предупреждений. Некоторые никак не реагируют на такую инициализацию, некоторые пишут что-то про приведение типа.
Вопрос: надо ли продолжать писать так или же стоит явно прописывать приведение типа, например, : m_value((std::uint64_t)(0)), или через static_cast? Как считается лучше всего делать? Я понимаю, что неявное приведение типа, конечно же выполняется, но может имеет смысл для читающего код человека показывать, что имелось ввиду?


Ответ

Нет никакого смысла использовать приведение типа. 0 - это константное выражение, можно сказать, "универсальный" литерал для скалярных и тем более арифметических типов. К тому же все статические объекты инициализируются нулем компилятором, то использование 0 в данном контексте в списке инициализации конструктора выглядит вполне естественно и не вызывает вопросов. Напротив, использование приведения типов может породить вопросы зачем это делается.

Какой наиболее правильный MIME для ответа с JSON?

Какое-то время, я отсылал ответ с JSON просто как простой текст: plain/text, однако, хотелось бы, наконец, отправлять правильный Content-Type-заголовок.
Вот некоторые из предлагаемых "стандартов" для JSON MIME:
application/json application/x-javascript text/javascript text/x-javascript text/x-json
Однако, какой из них верный или просто лучший относительно безопасности/поддержки клиентов (браузеры и т. п.)?
Перевод вопроса "What is the correct JSON content type?"


Ответ

Для JSON
Согласно регистрации IANA и RFC 4627: application/json в кодировке UTF-8
Для JSONP
application/javascript так же в UTF-8

Когда создателя JSON Дугласа Крофорда спросили почему не text/json, он ответил что это и не JS-скрипт, но и не текст, поэтому скорее application/*, чем text/*

Наследуется ли interface от System.Object?

Наследуется ли interface от System.Object?


Ответ

Нет.
В документации говорится:
Интерфейсы не содержат реализацию методов.

Если бы интерфейс каким-то образом наследовался от System.Object, он бы унаследовал реализацию его методов (например, ToString()), что противоречит документации.
Фактически в C# интерфейсы не считаются классами. Например, класс может наследовать только одному классу, но имплементировать при этом любое количество интерфейсов.

Как добавить смайлы в android приложение

Собственно необходимо добавить смайлы в android приложение в поля EditText и RecyclerView Есть ли существующие библиотеки?


Ответ

Библиотека не нужна. Смайлы, которые у вас доступны в телефоне закодированы в UNICODE. Все что нужно, это перевести правильно юникод(int) в строку. Вот ресурс на все смайлы с Unicode.
Перевод юникода в строку-смайл (код на котлине)
fun getEmojiByUnicode(unicode: Int): String = String(Character.toChars(unicode))
Если юникод приходит в виде строки, то можно перевести его в int так:
Integer.parseInt("юникод без превикса U+", 16)

Как правильно сделать git checkout на ветку

Сделал git clone с репо, моя ветка - master. Мне нужно переключится на другую ветку c удаленного репо, которой нет локально - test-branch. Если с мастера создаю ветку и тяну туда, тогда появляются конфликты и нужно все это мержить. А мне мержить не нужно, нужно просто переключится на удаленную ветку без изменений с мастера.
Вот когда я делаю так
git clone remote git checkout test-branch git pull origin test-branch
У меня сливается мастер и удаленная ветка test-branch, чего мне не нужно. Возможно есть способ для переключения на удаленную ветку без слияния ?


Ответ

Во первых, можно сразу клонировать нужную ветку
git clone -b
В вашем случае, можно создать локальную ветку во время checkout:
git checkout -b feat_branch origin/feat_branch
Либо, без непосредственного переключения:
git branch feat_branch origin/feat_branch

Что такое “псевдоним” для аргумента?

Читаю Джон Шарп - Microsoft Visual C#. Подробное руководство - 2017.
Разбираю тему с ref и out и там встречается такое примечание:

Уже второй, третий раз встречаю слово псевдоним.
Собственно вопрос: что такое псевдоним для аргумента в данном контексте или псевдоним в целом.


Ответ

Смотрите. «Обычные» параметры (без ref/out) передаются в метод по значению. Это значит, что если вы поменяете значение параметра внутри метода, то снаружи этого никто не заметит.
(Если вы поменяете не сам параметр ссылочного типа, а его поля/свойства, то это снаружи будет видно, но это уже другая история.)
Теперь, если у вас при параметре указан ref, то изменения этого параметра станут видны снаружи. То есть в коде
void Change(ref string s) { s = "Хихи"; }
string abc = "abc"; Change(ref abc);
будет изменена не копия ссылки abc на строку, а сама эта ссылка. Поэтому если вы теперь напишете
Console.WriteLine(abc);
— то выведено будет именно Хихи
Таким образом, имеется в виду, что s во время выполнения метода как бы просто другое имя (то есть, псевдоним) для имени abc

Внутренняя тень градиентом

Здравствуйте!
Мне нужно сделать внутреннюю тень у блока, но что бы она была под углом 45deg
Я пробовал такое сделать обычной тенью, но оно не так выглядит, как надо:
.shadow { width: 250px; height: 250px; box-shadow: inset 0px 0px 50px #000; }


Мне пришла в голову идея: сделать тень градиентом. Но я не знаю как.
Пример нужной тени:


Ответ

Предлагаю попробовать background
body { margin: 0; display: flex; } div { width: 100vmin; height: 100vmin; margin: auto; background: linear-gradient(45deg, transparent 70%, black 100%), linear-gradient(-45deg, transparent 70%, black 100%), linear-gradient(-135deg, transparent 70%, black 100%), linear-gradient(135deg, transparent 70%, black 100%) }


Рандомный оттенок

Хочу создать форму, где пользователь нажимает на нужный цвет и скрипт генерирует случайный оттенок этого цвета.
Я генерирую цвет rgb с помощью random. Но я не могу Придумать, как сделать, что бы генерировался именно оттенок цвета, а не случайный цвет
$(function() { $('#color').change(function() { var min = 0, max = 255; var rgbColor = 'rgb('+(Math.floor(Math.random() * (max - min)) + min)+','+(Math.floor(Math.random() * (max - min)) + min)+','+(Math.floor(Math.random() * (max - min)) + min)+')'; $('#shade').val(rgbColor).css('border-color', rgbColor); }); }); #shade {border: 2px solid #000;}

Выберите цвет:

Оттенок:


Как сделать, что бы генерировался оттенок?


Ответ

Нужно записывать кода всех оттенков нужных
$(function() { $('#color').change(function() { var self = this, // Создаём список цветов colorsModels = { 'red': {'r': '50-255', 'g': '0', 'b': '0'}, 'green': {'r': '0', 'g': '50-255', 'b': '0'}, 'yellow': {'r': '50-255', 'g': 'r', 'b': '0'}, 'blue': {'r': '0', 'g': '0', 'b': '50-255'}, 'grey': {'r': '50-200', 'g': 'r', 'b': 'r'} }; // Проверяем, существует ли цвет указанный в списке if( colorsModels[self.value] !== undefined ){ // Передаём массив цвета в переменную и создаём rgb var model = colorsModels[self.value], rgb = {r: null, g: null, b: null}; // Перебираем каждый цвет из массива for(var key in model){ if( /\d{1,3}\-\d{1,3}/.exec(model[key]) ){ // Проверяем, указано ли значение диапазоном // Вычисляем минимум и максимум с диапазона var min = parseFloat( model[key].replace(/(\d{1,3})\-\d{1,3}/, '$1') ), max = parseFloat( model[key].replace(/\d{1,3}\-(\d{1,3})/, '$1') ); // Вычисляем рандомное число в этом диапазоне var value = Math.floor(Math.random() * (max - min)) + min; // Применяем значение rgb[key] = value; }else if( /\d{1,3}/.exec(model[key]) ){ // Если цвет указан не диапазоном, то проверяем, цифра ли это // Преобразовываем значение в цифру var value = parseFloat( model[key] ); // Применяем значение rgb[key] = value; }else if( model[key] === 'r' || model[key] === 'g' || model[key] === 'b' ){ // Проверяем, ну казано ли значение повторяющим цветом (не равно ли значение пердыдущим цветам) // Проверяем, на допустимость повторения if( (key !== 'r' && key !== model[key]) || (model[key] === 'g' && key !== 'r') ){ // Если всё нормально, то копируем значение rgb[key] = rgb[model[key]]; }else{ console.error('Invalid!'); }; }else{ console.error('Undefined a value color!'); }; }; // Устанавливаем значение var rgbColor = 'rgb('+rgb['r']+','+rgb['g']+','+rgb['b']+')'; $('#shade').val(rgbColor).css('border-color', rgbColor); }else{ console.error('Undefined a color!'); }; }); }); #shade {border: 2px solid #000;}

Выберите цвет:

Оттенок:


Как перемешать строки текста в textarea на JQuery

Здравствуйте. Помогите перемешать строки в textarea средствами только JQuery
Есть форма, в ней только адреса сайтов которые всегда начинаются на http или https



Сертификат для KeyStore

Создаю хранилище для PrivateKey. В строке KeyStore.PrivateKeyEntry skEntry = new KeyStore.PrivateKeyEntry() в функцию PrivateKeyEntry() необходимо передать 2 параметра один из которых сам приватный ключ, а второй параметр это сертификат. Я не совсем понимаю как этот сертификат получить имея открытый и закрытый ключ. Весь кусок кода(строку в которой проблема выделил):
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(4096, new SecureRandom()); final KeyPair key = keyGen.generateKeyPair(); KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(password.getText().toString().toCharArray());
KeyStore.PrivateKeyEntry skEntry = new KeyStore.PrivateKeyEntry(?????????)
store.setEntry(nickname.getText().toString(), skEntry, protParam);


Ответ

Судя по вопросу вы не совсем понимаете основную проблему публичной криптографии. Главная ее проблема состоит в том, чтобы удостовериться, что публичный ключ принадлежит тому кто ее предъявляет.
Это аналогично тому, что человек приходит с ключом от квартиры, где бабки лежат и надо теперь удостовериться что это его квартира. В обычной жизни с такого человека затребуют документ подтверждающий что квартира принадлежит ему или по крайней мере он имеет какое-то отношение к ней (например договор аренды).
Точно такую же роль этого удостоверяющего документа в публичной криптографии имеет цифровой сертификат. В реале цифровые сертификаты генерируют доверенные центры, типа VeriSign, Thawte и проч. Их подписи распознаются нормальными браузерами и устройствами, поскольку они могут сверить слепок подписи (fingerprint) со слепками, которые хранятся в устройствах. Для интереса зайдите в своем Android устройстве в раздел Сертификаты безопасности - в настройках девайса или в любом настольном браузере в настройках, типа:
.
Вообще-то сертификация ключа стоит и денег и времени.
В вашем случае, вы сами генерируете на лету пару ключей и поэтому не сможете предъявить нормальный сертификат. На этот случай предусмотрена генерация т.н. Self Signed Certificate, то есть сертификата, который вы сами же и подписали своим же ключом. Возвращаясь к нашему примеру с квартирой, это аналог того, что - предъявитель ключа пишет расписку, типа: да, я имярек, мамой клянусь, что это моя квартира :)
Теперь ближе к делу. Вам надо cгенерировать т.н. SelfSigned сертификат стандарта X.509. Но здесь начинаются проблемы. Реализация класса X509Certificate из коробки подразумевает его создания только из битового массива или из InputStream, Selfsign реализован, но почему-то скрыт от широкой общественности. Подробнее об этом здесь
К счастью есть такая либа как Bouncy Castle, в котором это можно относительно легко сделать.
Но опять же к несчастью, напрямую использовать Bouncy Castle в Android нельзя так как Google по неизвестным причинам его уже использует в коде Android, но в каком то урезанном виде, так что 90% Bouncy Castle неработоспособны. То есть при попытке включить библиотеку Bouncy Castle в ваш код, будет выдана ошибка о задвоении.
Опять же к счастью (мир не без добрых людей) - умные люди написали Spongy Castle - специальный порт Bouncy Castle для Android'а который избавлен от конфликта имен.
Ну вот теперь:
Импортируем Spongy Castle через Gradle Читаем как генерировать сертификат
P.S. Уффф... зачем я так много написал? Наверное в честь пятницы

Отключение/Включение СОМ-порта

Ребят, подскажите, как можно отключить, а потом включить СОМ-порт программно?
Бывает, что порты отваливаются, и нужно их перезапустить через диспетчер устройств. Хотелось бы реализовать это программно.
Операционная система: Windows 10


Ответ

Вы можете включить/отключить устройства от Win32 (и, следовательно, из C# с помощью P/Invoke) с использованием SetupDi API, но не все устройства таким образом можно отключить.
Проблему Вы будете получать, например, при попытке отключения тачпада от Win32 (или WMI или любой другой API, который вызывает из в SetupDi*- семейства функций). Причина в том, что драйвер мыши по умолчанию, которые в большинстве ноутбуков с сенсорной панелью ("PS/2-совместимая мышь"), не поддерживает отключение с помощью SetupDi API. Возможно это может быть потому, что старые мыши, использующие PS/2 - разъем не могут быть отсоединены на горячую без перезагрузки оборудования.
Для того, чтобы убедиться в том, что Вы можете отключить устройство, перейдите в Диспетчер устройств и щелкните правой кнопкой мыши на устройстве мыши в списке устройств. Если там есть опция Отключить и она активна, то Вы можете использовать SetupDi, чтобы отключить это устройство. Если нет опции отключения - увы, не повезло, этого сделать не получится.
Если Вы видите опцию Отключить, то приведенный код ниже должен позволить Вам отключить и повторно включить устройство.
Код для вызова вспомогательной библиотеки:
public static void EnableMouse(bool enable) { // every type of device has a hard-coded GUID, this is the one for mice Guid mouseGuid = new Guid("{4d36e96f-e325-11ce-bfc1-08002be10318}");
// get this from the properties dialog box of this device in Device Manager string instancePath = @"ACPI\PNP0F03\4&3688D3F&0";
DeviceHelper.SetDeviceEnabled(mouseGuid, instancePath, enable); }
Вот сама вспомогательная библиотека, взято отсюда
using System; using System.Text; using System.Collections.Generic; using DisableDevice; using System.Runtime.InteropServices; using System.ComponentModel; using Microsoft.Win32.SafeHandles; using System.Security; using System.Runtime.ConstrainedExecution; using System.Management;
namespace DisableDevice {
[Flags()] internal enum SetupDiGetClassDevsFlags { Default = 1, Present = 2, AllClasses = 4, Profile = 8, DeviceInterface = (int)0x10 }
internal enum DiFunction { SelectDevice = 1, InstallDevice = 2, AssignResources = 3, Properties = 4, Remove = 5, FirstTimeSetup = 6, FoundDevice = 7, SelectClassDrivers = 8, ValidateClassDrivers = 9, InstallClassDrivers = (int)0xa, CalcDiskSpace = (int)0xb, DestroyPrivateData = (int)0xc, ValidateDriver = (int)0xd, Detect = (int)0xf, InstallWizard = (int)0x10, DestroyWizardData = (int)0x11, PropertyChange = (int)0x12, EnableClass = (int)0x13, DetectVerify = (int)0x14, InstallDeviceFiles = (int)0x15, UnRemove = (int)0x16, SelectBestCompatDrv = (int)0x17, AllowInstall = (int)0x18, RegisterDevice = (int)0x19, NewDeviceWizardPreSelect = (int)0x1a, NewDeviceWizardSelect = (int)0x1b, NewDeviceWizardPreAnalyze = (int)0x1c, NewDeviceWizardPostAnalyze = (int)0x1d, NewDeviceWizardFinishInstall = (int)0x1e, Unused1 = (int)0x1f, InstallInterfaces = (int)0x20, DetectCancel = (int)0x21, RegisterCoInstallers = (int)0x22, AddPropertyPageAdvanced = (int)0x23, AddPropertyPageBasic = (int)0x24, Reserved1 = (int)0x25, Troubleshooter = (int)0x26, PowerMessageWake = (int)0x27, AddRemotePropertyPageAdvanced = (int)0x28, UpdateDriverUI = (int)0x29, Reserved2 = (int)0x30 }
internal enum StateChangeAction { Enable = 1, Disable = 2, PropChange = 3, Start = 4, Stop = 5 }
[Flags()] internal enum Scopes { Global = 1, ConfigSpecific = 2, ConfigGeneral = 4 }
internal enum SetupApiError { NoAssociatedClass = unchecked((int)0xe0000200), ClassMismatch = unchecked((int)0xe0000201), DuplicateFound = unchecked((int)0xe0000202), NoDriverSelected = unchecked((int)0xe0000203), KeyDoesNotExist = unchecked((int)0xe0000204), InvalidDevinstName = unchecked((int)0xe0000205), InvalidClass = unchecked((int)0xe0000206), DevinstAlreadyExists = unchecked((int)0xe0000207), DevinfoNotRegistered = unchecked((int)0xe0000208), InvalidRegProperty = unchecked((int)0xe0000209), NoInf = unchecked((int)0xe000020a), NoSuchHDevinst = unchecked((int)0xe000020b), CantLoadClassIcon = unchecked((int)0xe000020c), InvalidClassInstaller = unchecked((int)0xe000020d), DiDoDefault = unchecked((int)0xe000020e), DiNoFileCopy = unchecked((int)0xe000020f), InvalidHwProfile = unchecked((int)0xe0000210), NoDeviceSelected = unchecked((int)0xe0000211), DevinfolistLocked = unchecked((int)0xe0000212), DevinfodataLocked = unchecked((int)0xe0000213), DiBadPath = unchecked((int)0xe0000214), NoClassInstallParams = unchecked((int)0xe0000215), FileQueueLocked = unchecked((int)0xe0000216), BadServiceInstallSect = unchecked((int)0xe0000217), NoClassDriverList = unchecked((int)0xe0000218), NoAssociatedService = unchecked((int)0xe0000219), NoDefaultDeviceInterface = unchecked((int)0xe000021a), DeviceInterfaceActive = unchecked((int)0xe000021b), DeviceInterfaceRemoved = unchecked((int)0xe000021c), BadInterfaceInstallSect = unchecked((int)0xe000021d), NoSuchInterfaceClass = unchecked((int)0xe000021e), InvalidReferenceString = unchecked((int)0xe000021f), InvalidMachineName = unchecked((int)0xe0000220), RemoteCommFailure = unchecked((int)0xe0000221), MachineUnavailable = unchecked((int)0xe0000222), NoConfigMgrServices = unchecked((int)0xe0000223), InvalidPropPageProvider = unchecked((int)0xe0000224), NoSuchDeviceInterface = unchecked((int)0xe0000225), DiPostProcessingRequired = unchecked((int)0xe0000226), InvalidCOInstaller = unchecked((int)0xe0000227), NoCompatDrivers = unchecked((int)0xe0000228), NoDeviceIcon = unchecked((int)0xe0000229), InvalidInfLogConfig = unchecked((int)0xe000022a), DiDontInstall = unchecked((int)0xe000022b), InvalidFilterDriver = unchecked((int)0xe000022c), NonWindowsNTDriver = unchecked((int)0xe000022d), NonWindowsDriver = unchecked((int)0xe000022e), NoCatalogForOemInf = unchecked((int)0xe000022f), DevInstallQueueNonNative = unchecked((int)0xe0000230), NotDisableable = unchecked((int)0xe0000231), CantRemoveDevinst = unchecked((int)0xe0000232), InvalidTarget = unchecked((int)0xe0000233), DriverNonNative = unchecked((int)0xe0000234), InWow64 = unchecked((int)0xe0000235), SetSystemRestorePoint = unchecked((int)0xe0000236), IncorrectlyCopiedInf = unchecked((int)0xe0000237), SceDisabled = unchecked((int)0xe0000238), UnknownException = unchecked((int)0xe0000239), PnpRegistryError = unchecked((int)0xe000023a), RemoteRequestUnsupported = unchecked((int)0xe000023b), NotAnInstalledOemInf = unchecked((int)0xe000023c), InfInUseByDevices = unchecked((int)0xe000023d), DiFunctionObsolete = unchecked((int)0xe000023e), NoAuthenticodeCatalog = unchecked((int)0xe000023f), AuthenticodeDisallowed = unchecked((int)0xe0000240), AuthenticodeTrustedPublisher = unchecked((int)0xe0000241), AuthenticodeTrustNotEstablished = unchecked((int)0xe0000242), AuthenticodePublisherNotTrusted = unchecked((int)0xe0000243), SignatureOSAttributeMismatch = unchecked((int)0xe0000244), OnlyValidateViaAuthenticode = unchecked((int)0xe0000245) }
[StructLayout(LayoutKind.Sequential)] internal struct DeviceInfoData { public int Size; public Guid ClassGuid; public int DevInst; public IntPtr Reserved; }
[StructLayout(LayoutKind.Sequential)] internal struct PropertyChangeParameters { public int Size; // part of header. It's flattened out into 1 structure. public DiFunction DiFunction; public StateChangeAction StateChange; public Scopes Scope; public int HwProfile; }
internal class NativeMethods {
private const string setupapi = "setupapi.dll";
private NativeMethods() { }
[DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiCallClassInstaller(DiFunction installFunction, SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData deviceInfoData);
[DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiEnumDeviceInfo(SafeDeviceInfoSetHandle deviceInfoSet, int memberIndex, ref DeviceInfoData deviceInfoData);
[DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)] public static extern SafeDeviceInfoSetHandle SetupDiGetClassDevs([In()] ref Guid classGuid, [MarshalAs(UnmanagedType.LPWStr)] string enumerator, IntPtr hwndParent, SetupDiGetClassDevsFlags flags);
/* [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetDeviceInstanceId(SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData did, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder deviceInstanceId, int deviceInstanceIdSize, [Out()] ref int requiredSize); */ [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiGetDeviceInstanceId( IntPtr DeviceInfoSet, ref DeviceInfoData did, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder DeviceInstanceId, int DeviceInstanceIdSize, out int RequiredSize );
[SuppressUnmanagedCodeSecurity()] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);
[DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetupDiSetClassInstallParams(SafeDeviceInfoSetHandle deviceInfoSet, [In()] ref DeviceInfoData deviceInfoData, [In()] ref PropertyChangeParameters classInstallParams, int classInstallParamsSize);
}
internal class SafeDeviceInfoSetHandle : SafeHandleZeroOrMinusOneIsInvalid {
public SafeDeviceInfoSetHandle() : base(true) { }
protected override bool ReleaseHandle() { return NativeMethods.SetupDiDestroyDeviceInfoList(this.handle); }
}
public sealed class DeviceHelper {
private DeviceHelper() { }
///

/// Enable or disable a device. /// /// The class guid of the device. Available in the device manager. /// The device instance id of the device. Available in the device manager. /// True to enable, False to disable. /// Will throw an exception if the device is not Disableable. public static void SetDeviceEnabled(Guid classGuid, string instanceId, bool enable) { SafeDeviceInfoSetHandle diSetHandle = null; try { // Get the handle to a device information set for all devices matching classGuid that are present on the // system. diSetHandle = NativeMethods.SetupDiGetClassDevs(ref classGuid, null, IntPtr.Zero, SetupDiGetClassDevsFlags.Present); // Get the device information data for each matching device. DeviceInfoData[] diData = GetDeviceInfoData(diSetHandle); // Find the index of our instance. i.e. the touchpad mouse - I have 3 mice attached... int index = GetIndexOfInstance(diSetHandle, diData, instanceId); // Disable... EnableDevice(diSetHandle, diData[index], enable); } finally { if (diSetHandle != null) { if (diSetHandle.IsClosed == false) { diSetHandle.Close(); } diSetHandle.Dispose(); } } }
private static DeviceInfoData[] GetDeviceInfoData(SafeDeviceInfoSetHandle handle) { List data = new List(); DeviceInfoData did = new DeviceInfoData(); int didSize = Marshal.SizeOf(did); did.Size = didSize; int index = 0; while (NativeMethods.SetupDiEnumDeviceInfo(handle, index, ref did)) { data.Add(did); index += 1; did = new DeviceInfoData(); did.Size = didSize; } return data.ToArray(); }
// Find the index of the particular DeviceInfoData for the instanceId. private static int GetIndexOfInstance(SafeDeviceInfoSetHandle handle, DeviceInfoData[] diData, string instanceId) { const int ERROR_INSUFFICIENT_BUFFER = 122; for (int index = 0; index <= diData.Length - 1; index++) { StringBuilder sb = new StringBuilder(1); int requiredSize = 0; bool result = NativeMethods.SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData[index], sb, sb.Capacity, out requiredSize); if (result == false && Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) { sb.Capacity = requiredSize; result = NativeMethods.SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData[index], sb, sb.Capacity, out requiredSize); } if (result == false) throw new Win32Exception(); if (instanceId.Equals(sb.ToString())) { return index; } } // not found return -1; }
// enable/disable... private static void EnableDevice(SafeDeviceInfoSetHandle handle, DeviceInfoData diData, bool enable) { PropertyChangeParameters @params = new PropertyChangeParameters(); // The size is just the size of the header, but we've flattened the structure. // The header comprises the first two fields, both integer. @params.Size = 8; @params.DiFunction = DiFunction.PropertyChange; @params.Scope = Scopes.Global; if (enable) { @params.StateChange = StateChangeAction.Enable; } else { @params.StateChange = StateChangeAction.Disable; }
bool result = NativeMethods.SetupDiSetClassInstallParams(handle, ref diData, ref @params, Marshal.SizeOf(@params)); if (result == false) throw new Win32Exception(); result = NativeMethods.SetupDiCallClassInstaller(DiFunction.PropertyChange, handle, ref diData); if (result == false) { int err = Marshal.GetLastWin32Error(); if (err == (int)SetupApiError.NotDisableable) throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager)."); else if (err >= (int)SetupApiError.NoAssociatedClass && err <= (int)SetupApiError.OnlyValidateViaAuthenticode) throw new Win32Exception("SetupAPI error: " + ((SetupApiError)err).ToString()); else throw new Win32Exception(); } } } }
Данный ответ взят с en SO, переведен и дополнен мной. Ссылка на источник: Win32 API function to programmatically enable/disable device
У каждого типа устройства есть жестко запрограммированный GUID, для мышки - он один, для COM-порта - другой, и так для всех устройств. Вам необходимо найти нужный GUID и instancePath и подставить в верхнем блоке кода. Данную информацию можно найти в разделе Диспетчер устройств в сведениях об устройстве.
Также, для корректной работы программы рекомендуется компилировать приложение в конфигурации AnyCPU, при этом среда разработки должна быть запущена с правами Администратора, иначе не будет прав доступа.

Переопределение поведения HttpClient

Задумал я исправить косяки родного HttpClient. Разумно предположить, что все методы сходятся к SendAsync, а значит нужно переопределять его в наследнике и даже виртуальный он.
Но оказалось, что виртуальная только одна его перегрузка, а внутренние методы HttpClient ходят через другие перегрузки и потому в наследник не попадают.
Это косяк разработчика класса HttpClient или я чего-то не понимаю в наследовании? Зачем объявлять одну перегрузку virtual, если перегружать ее бесполезно?


Ответ

Все дело в том, что метод SendAsync не предназначен для расширения. И он не виртуальный, а override метод базового класса HttpMessageInvoker.
Расширять же HttpClient задумано через HttpMessageHandler/DelegatingHandler из которых (собственные реализации через наследование) можно составить цепочку декораторов последовательно обрабатывающих запрос.
Пример:
Проблема 1: HttpClient при таймауте кидает OperationCanceledException, что сбивает с толку и вызывает необходимость вручную проверять "действительно ли была отмена"
Пишем FixTimeoutHandler для подмены исключений. Увы, в SendAsync прокидывается чужой CancellationToken с чужим CancellationTokenSource (есть предположение, что реализация таймаута на нем построена), поэтому в конструктор прокидываем родной CancellationToken и у него проверяем "была ли реальная отмена"
public class FixTimeoutHandler : DelegatingHandler { private CancellationToken _cancellationToken;
public FixTimeoutHandler( HttpClientHandler innerHandler, CancellationToken cancellationToken) : base(innerHandler) { _cancellationToken = cancellationToken; }
protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var requestTask = base.SendAsync(request, cancellationToken);
var endTask = requestTask.ContinueWith( t => { if (t.IsCanceled) { //проверяем родной токен, а не тот, что нам дает метод if (_cancellationToken.IsCancellationRequested) throw new OperationCanceledException(cancellationToken); throw new HttpRequestException("Timeout"); }
if (t.IsFaulted) { var ex = t.Exception; ex.Data["RequestUrl"] = request.RequestUri.ToString(); ex.Data["RequestMethod"] = request.Method.Method; throw ex; }
return t.Result; }, TaskContinuationOptions.ExecuteSynchronously );
return endTask; } }
Проблема 2: Повторять запрос при сетевых ошибках (в том числе и по таймауту, который мы хендлером FixTimeoutHandler определили в сетевые ошибки. Любая другая ошибка пролетит выше по стеку.
Упрощенная реализация
public class RepeatHandler : DelegatingHandler { public RepeatHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { for (var i = 0; i < 3; i++) try { var result = await base.SendAsync(request, cancellationToken).ConfigureAwait(true); return result; } catch (HttpRequestException){}
throw new HttpRequestException("Error"); } }
Последний в цепочке HttpClientHandler, который делает http запросы.
Собираем вместе:
var cts = new CancellationTokenSource(); var http = new HttpClient(new RepeatHandler(new FixTimeoutHandler(new HttpClientHandler(),_cts.Token))) { Timeout = TimeSpan.FromSeconds(3) }; var result=await http.GetAsync("http://localhost/sleep.php", _cts.Token);
Также есть класс-фабрика HttpClientFactory для сбора цепочек хендлеров, но он лежит в отдельной сборке, которую нужно ставить через nuget

Что означает точка в выражении 1/60.?

Заметил, что значения выражений
double x = 1234 + 1/60.
и
double x = 1234 + 1/60
разные.
Почему?


Ответ

Потому что без точки идет целочисленное деление и в итоге получится не дробное, а целое число (в данном случае получится ноль, т.к. результат округляется вниз к целому числу).
Точка намекает, что число не целое и результат деления будет типа double (0.016666666666666666).
Для успокоения души можно писать и 1/60.0, но достаточно и просто точки после числа.

Документация (summary) во внешнем файле

Имеется библиотека. В ней методы, поля (свойства), которые хорошо бы описать, чтобы при использовании Visual Studio высвечивала описание и подсказки для того или иного поля/метода.
Я знаю, что можно писать

прямо в коде и в свойствах сборки добавить галочку для создания XML-документации.
Но если я сейчас прямо в коде начну писать описание, то код заметно удлинится. Можно ли как-то в отдельном файле написать эту документацию?
Чтобы в коде не было , но IntelliSense смог отображать эту информацию?


Ответ

Да, это возможно. Используйте тег include. Теперь достаточно
Аннотировать нужный метод так:
/// public void MethodName(string arg) { } Создать файл external_summary.xml, имеющий такую структуру:

Описание метода Описание параметра arg
В результате после компиляции сборки с опцией /doc вы получите следующую xml-документацию:
Application Описание метода Описание параметра arg

Не работает transition при right 0

Добрый день.
Есть такая проблема при наведении на блок с position: absolute он должен плавно переехать в правую сторону right: 0, но у меня не получается это сделать думал что transition это исправит.
Вот код https://jsfiddle.net/j9zz6uxp/
.position{ display: block; position: absolute; width: 56px; height: 66px; background: red; top: 20px; left: 120px; margin-left: -28px; transition: all 1.1s; z-index: 999; }
.position:hover{ margin-left:auto; right: 0; }
Прошу вашей помощи.


Ответ

.position{ display: block; position: absolute; width: 56px; height: 66px; background: red; top: 20px; left: 120px; margin-left: -28px; transition: all 1.1s ease-in-out; z-index: 999; } .position:hover{ margin-left:auto; left: 100%; }


Вы с left на right меняете св-во при наведении, а нужно что-то одно

Вопрос про модель в MVC

Здравствуйте, я смотрел, как делают два разных человека сайт и так и не понял, откуда брать данные из БД в модели или контроллере? ну, т.е. в модели мы пишем табл из который будет выборка, это понятно.
Один человек делал так: в модели название табл и все. А выборку он делал уже в контроллере, например:
$feeds = Feedback::find()->orderBy('RAND()')->limit(4)->all();
А другой выборку делал в модели, а в контроллере уже обращался к методу того класса, пример:
$categories = Category::getCategoriesList();
Как правильно или как лучше и что лучше всего делать в модели?)))


Ответ

Для примера возьмем ваш пример. Выводим $feeds = Feedback::find()->orderBy('RAND()')->limit(4)->all(); в контроллере и все работает. Завтра нужно тоже самое, но в другом контроллере (или методе)? Что тогда? Вот если мы создадим метод в модели, то сможем использовать все это и в других контроллерах.
public function getFeeds() { return self::find()->orderBy('RAND()')->limit(4)->all(); }
Тут даже дело уже не в самом MVC, а в подходе к гибкости системы. Старайтесь всегда думать о том, что вдруг данный код понадобиться где-то ещё.
Я использую помимо моделей (Models) ещё и модели представления (ViewModels). Это очень удобно. Например есть модель Users
class Users extends ActiveRecord {
public static function tableName() { return 'users'; }
//Behaviors... //Roles... //Relations
}
В данной модели я храню все методы, касаемо самого Yii (правила,связи, поведения и т.д.). Не засоряю данный класс. Для остальных же методов использую UsersViewModel
class UsersViewModel extends Users {
public static function getAllUsers() { return Users::find()->all(); }
}
Я привел для примера примитивный пример, но важна сама суть. Старайтесь всегда думать на шаг вперед, чтобы потом не возвращаться на 2 шага назад.
Лучшие практики MVC. На примере Yii

Работа в фоновом режиме (Xamarin)

Подскажите как можно решить данный кейс для iOS 9+, Android 4.4+ и WP 8.1+
Программа раз в день должна проверять счёт пользователя и если он меньше 30 руб. то уведомлять.
Как реализовать уведомления на трех платформах я разобрался
А вот заставить программу работать постоянно (как сервис в Windows) не ясно и получиться ли это реализовать кроссплатформенно?
P.S. Пишу свое первое приложение для мобилок.


Ответ

То, что Вы хотите, называется Push Notification-ом. То, что Вы указали в примере - это локальное уведомление, по сути, c таймером на исполнение. Указали тайтл, текст, время, и вуаля, заданный текст показался в нужное время. В Вашем случае, такой вариант не подойдет просто потому, что счёт пользователя, как я понял - некое хранилище средств, лежащее извне, и для его проверки, понадобится исполнение кода приложения, а значит, приложение должно быть запущено. В случае с Пушем все проще, так как тут даже не нужна работа приложения, Вам нужен сервер который скажет, что нужно отправить уведомление.
Если я ошибаюсь, и его счёт сугубо виртуальная валюта, которая пополняется со временем - рассчитать время заполнения или растраты - не трудно, достаточно знать его потребление на момент изменения. Что касается первого варианта, если счета пользователя - некое подобие кошельков на Вашем сервере, то Вам понадобится только промежуточный сервис отправки подобных уведомлений, к примеру: FCM (Android), APNS (iOS), WNS (Windows). Ваш сервер через подобный сервис будет сам уведомлять пользователя о малом количестве средств.
Можете прочесть более подробно тут: Основы успешной реализации push-уведомлений для мобильных приложений

Слушатель клавиши Python

Как сделать слушателя кнопки в Питоне? Аля: нажал на клавишу CTRL -> выполнилась функция f()
Windows/Python 3.6.0


Ответ

Например, pynput (pip install pynput). Пример из официальной документации:
from pynput import keyboard
def on_press(key): try: print('alphanumeric key {0} pressed'.format(key.char)) except AttributeError: print('special key {0} pressed'.format(key))
def on_release(key): print('{0} released'.format(key)) if key == keyboard.Key.esc: # Stop listener return False
# Collect events until released with keyboard.Listener( on_press=on_press, on_release=on_release) as listener: listener.join()
Жрет любые символы (Fn+, *.Lock(NumLock, CapsLock), Alt - все, что угодно).
Чтобы прекратить слушать вам необходимо бросить исключение StopException или вернуть False из обработчика. Функции on_press, on_release автоматически исполняются не в основном потоке.
Как бонус дополнительно можно слушать события мыши.

Граница исчезает по кругу

Как сделать последнюю часть вращающегося круга постепенно исчезающей?
#loader-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; } #loader { display: block; position: relative; left: 50%; top: 50%; width: 150px; height: 150px; margin: -75px 0 0 -75px; border-radius: 50%; border: 5px solid transparent; border-top-color: #aaa; border-right-color: #aaa; animation: spin 2s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }


Я попытался использовать градиент, но он преобразует круг в квадрат.
Перевод ответа: Border fade in circle @Cornwell


Ответ

Круг с фоновым градиентом, псевдоэлемент поверх и clip-path с SVG-фоллбеком, чтобы немного этот круг обрезать.
#clip-svg { display: none; } .loader { width: 200px; height: 200px; border-radius: 200px; background-image: linear-gradient(#999, #fff); position: relative; -webkit-clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 50% 100%, 0% 100%); clip-path: url(#clip); clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 50% 100%, 0% 100%); animation: spin linear 2s infinite; } .loader:after { position: absolute; content: ''; left: 10px; top: 10px; width: 180px; height: 180px; border-radius: inherit; background-color: #fff; } @keyframes spin { to { transform: rotate(1turn) } }


Вариант с CSS-переменными и «HTML API».
#clip-svg { display: none; } .loader { width: calc(var(--radius, 100px) * 2); height: calc(var(--radius, 100px) * 2); border-radius: var(--radius, 100px); background-image: linear-gradient(#999, #fff); position: relative; -webkit-clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 50% 100%, 0% 100%); clip-path: url(#clip); clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 50% 100%, 0% 100%); animation: spin linear 2s infinite; } .loader:after { position: absolute; content: ''; left: var(--width, 10px); top: var(--width, 10px); width: calc(var(--radius, 100px) * 2 - var(--width, 10px) * 2); height: calc(var(--radius, 100px) * 2 - var(--width, 10px) * 2); border-radius: inherit; background-color: #fff; } @keyframes spin { to { transform: rotate(1turn) } }

Новая строка в ListView при добавлении с БД, принимает значения ранее удаленной

Есть список на основе ListView и SimpleCursorAdapter и SQLite.
Пишу Swipe строки списка с помощью анимации. В ACTION_MOVE строка списка должна двигаться влево за пальцем и при достижении определенного значения по оси X менять цвет и ставать доступной для удаления. В этой зоне при ACTION_UP строка должна удалиться с БД по найденому ID. Соответствующе в перерисованом ListView строка с удаляемой позицией исчезает из списка на экране. Все это работает, но возникает следующая проблемма:
При добавлении в БД новой строки она появляется в списке на экране в том состоянии и в том положении по оси X которое было у ранее удаленной строки.
Предполагаю что, скорее всего, где-то ListView держит ранее использованные вьюхи с теми характеристиками с которыми они были ранее удалены и заливает туда новые строки с БД.
Пробовал применять после удаления: notifyDataSetChanged(), завершение анимации - эффекта нет.
public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener, LoaderManager.LoaderCallbacks {
DB db; DBHelper dbHelper; SimpleCursorAdapter scAdapter; Context context; String name; String kind;
private View onTouchedItemView;
ListView lv_list; Button btnEmpty, btnAdd, btnRead, btnClear; TextView tvNameId, tvNameName, tvNameKind, tvNameCost; EditText tvName, tvKind;
private int pointDownX; private int pointDownY; private long touchedItemID;
private int targetPoint;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
db = new DB(this); db.open();
String[] from = new String[]{DB.KEY_ID, DB.KEY_NAME, DB.KEY_KIND, DB.KEY_COST}; int[] to = new int[]{R.id.tvListId, R.id.tvListName, R.id.tvListKind, R.id.tvListCost};
scAdapter = new SimpleCursorAdapter(this, R.layout.item, null, from, to, 0);
lv_list = (ListView) findViewById(R.id.lv_list); lv_list.setAdapter(scAdapter);
lv_list.setOnTouchListener(this); getSupportLoaderManager().initLoader(0, null, this);
tvNameId = (TextView) findViewById(R.id.tvNameId); tvNameName = (TextView) findViewById(R.id.tvNameName); tvNameKind = (TextView) findViewById(R.id.tvNameKind); tvNameCost = (TextView) findViewById(R.id.tvNameCost);
tvName = (EditText) findViewById(R.id.tvName); tvName.setOnClickListener(this);
tvKind = (EditText) findViewById(R.id.tvKind); tvKind.setOnClickListener(this);
btnAdd = (Button) findViewById(R.id.btnAdd); btnAdd.setOnClickListener(this);
btnEmpty = (Button) findViewById(R.id.btnEmpty); btnEmpty.setOnClickListener(this);
btnRead = (Button) findViewById(R.id.btnRead); btnRead.setOnClickListener(this);
btnClear = (Button) findViewById(R.id.btnClear); btnClear.setOnClickListener(this); }
@Override public void onClick(View view) { name = tvName.getText().toString(); kind = tvKind.getText().toString();
switch (view.getId()) { case R.id.btnAdd: if (kind.isEmpty()) { kind = "1"; } if (name.isEmpty()) { Toast.makeText(getApplicationContext(), "Fill all fields", Toast.LENGTH_SHORT).show(); } else { db.addRec(name, kind); getSupportLoaderManager().getLoader(0).forceLoad(); tvName.setText(""); tvKind.setText(""); } break;
case R.id.btnEmpty: tvName.setText(""); tvKind.setText(""); break;
case R.id.btnRead: getSupportLoaderManager().getLoader(0).forceLoad(); break;
case R.id.btnClear: db.delAllRec(); getSupportLoaderManager().getLoader(0).forceLoad(); break; } }
@Override public Loader onCreateLoader(int id, Bundle bndl) { return new MyCursorLoader(this, db); }
@Override public void onLoadFinished(Loader loader, Cursor cursor) { scAdapter.swapCursor(cursor); }
@Override public void onLoaderReset(Loader loader) { }
@Override public boolean onTouch(View v, MotionEvent event) {
int dispWidth = v.getWidth(); int horizontalMinDistance = dispWidth / 4; int distFromRightBorder = dispWidth - pointDownX; int distToMeet = pointDownX / 10;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: pointDownX = (int) event.getX(); pointDownY = (int) event.getY();
onTouchedItemView = lv_list.getChildAt(lv_list.pointToPosition(pointDownX, pointDownY)); touchedItemID = lv_list.pointToRowId(pointDownX, pointDownY);
return true;
case MotionEvent.ACTION_MOVE: int pointMovingX = (int) event.getX(); int deltaX = pointDownX - pointMovingX;
int distGone = distFromRightBorder / distToMeet * Math.abs(deltaX);
if (deltaX < 0) {
if (Math.abs(deltaX) < distToMeet) { targetPoint = dispWidth - pointMovingX + pointDownX - distGone;
} else { targetPoint = pointMovingX;
} anim();
} else {
if (Math.abs(deltaX) < distToMeet) { targetPoint = pointMovingX - dispWidth + distFromRightBorder - distGone;
} else { targetPoint = pointMovingX - dispWidth;
if (Math.abs(deltaX) > horizontalMinDistance && pointMovingX < dispWidth / 8) { onTouchedItemView.setBackgroundResource(R.color.deletemarker);
} else { onTouchedItemView.setBackgroundResource(R.color.backgroundmain); } } anim(); } return true;
case MotionEvent.ACTION_UP: float upX = (int) event.getRawX();
if (upX < dispWidth / 8) {
db.delRec(touchedItemID);
getSupportLoaderManager().getLoader(0).forceLoad();
} else { targetPoint = 0; anim(); } return true; } return true; }
public void anim() { onTouchedItemView.animate() .x(targetPoint) .setDuration(0) .start(); }
private static class MyCursorLoader extends CursorLoader { DB db;
public MyCursorLoader(Context context, DB db) { super(context); this.db = db; }
@Override public Cursor loadInBackground() { Cursor cursor = db.getAllData(); return cursor; } }
protected void onDestroy() { super.onDestroy(); db.close(); } }


Ответ

Нашел решение.
Применил обратную анимацию перед обновлением списка.
onTouchedItemView.setBackgroundResource(R.color.backgroundmain); targetPoint = 0; anim();
И метод:
clearDisappearingChildren();
Он удаляет анимацию на удаленном элементе списка.
В коде выглядит так:
case MotionEvent.ACTION_UP:
float upX = (int) event.getRawX();
if (upX < dispWidth / 8) {
db.delRec(touchedItemID);
lv_list.clearDisappearingChildren();
getSupportLoaderManager().getLoader(0).forceLoad(); onTouchedItemView.setBackgroundResource(R.color.backgroundmain); targetPoint = 0; anim();
} else {
targetPoint = 0; anim();
} return true;

Что такое BDD в чём его отличия от TDD?

Что такое BDD и в чём его отличия от TDD?


Ответ

BDD - behaviour-driven development - это разработка, основанная на описании поведения. То есть, есть специальный человек(или люди) который пишет описания вида "я как пользователь хочу когда нажали кнопку пуск тогда показывалось меню как на картинке". (там есть специально выделенные ключевые слова). Программисты давно написали специальные тулы (например, cucumber), которые подобные описания переводят в тесты (иногда совсем прозрачно для программиста). А дальше классическая разработка с тестами.
В чем преимущество BDD?
тесты читаемые для не программистов. их легко изменять. Они часто пишутся почти на чистом английском. их теперь может писать product owner или другие заинтересованные лица. результаты выполнения тестов более "человечные". тесты не зависят от целевого языка программирования. Миграция на другой язык сильно упрощается.
(слово тесты выделено не случайно, потому что теперь тесты это и описания, и непосредственно их реализация.)

ItemsControl: Доступ из элемента к сведениям о родителе

Имеется следующая разметка:




Здесь Items - некая коллекция элементов, упорядоченная по убыванию Weight. Что я хочу: подложить под TextBlock'и зеленый прямоугольник, но так, чтобы его ширина была пропорциональна значению Weight, причем за 100% принять большее значение (оно самое первое будет). Шаблон набросал, но что вписать в свойство Width никак не соображу. Тут надо, во-первых, учесть что эти 100% заведомо неизвестны, а во-вторых, что ширина Grid может быть любой.
Нарисовал что хочу получить:


Ответ

Если максимальный вес есть отдельно в VM, то получается такой вот код:




На Windows 7 выглядит так:

Если хотите, чтобы стиль был один и тот же, проще всего таки приспособить прямоугольник. Для этого концептуально проще всего использовать конвертер.
Например, так. Ширина прямоугольника равна доступной ширине грида, умноженной на отношение Weight к MaxWeight. Оформляем это в виде конвертера.
class ProportionConverter : IMultiValueConverter { public object Convert(object[] values, Type t, object p, CultureInfo ci) => (double)values[0] / (double)values[1] * (double)values[2];
public object[] ConvertBack(object value, Type[] tt, object p, CultureInfo ci) => throw new NotSupportedException(); }
И оформляем такую разметку:




Результат:


Для эстетов, которые не хотят плодить конвертеры, можно извратиться, и реализовать деление при помощи двух трансформаций, причём одну из них нужно обратить. Вот так:

Картинка получается та же.
Ещё один вариант, который предложил в комментариях @Pavel Mayorov

(Я пробовал ещё варианты с GradientBrush и RenderTransform через конвертер, они тоже работают.)

Динамическое выделение памяти для виджета верхнего уровня

Начал изучение Qt и на определенном этапе встал вопрос с освобождением памяти, вот пример кода:
int main(int argc, char *argv[]) { QApplication a(argc, argv); Spin(); return a.exec(); }
void Spin() { QSpinBox *psb = new QSpinBox(); psb->show(); }
Верно ли так выделять память для виджета верхнего уровня в локальной функции и нигде далее не освобождать память для него?


Ответ

QObject в своём деструкторе выполняет освобождение памяти дочерних элементов. Т.е. элементов, у которых Parent установлен на уничтожаемый элемент. Например:
QObject* p = new QObject(); QObject* c1 = new QObject(p); QObject* c2 = new QObject(); c2->setParent(p);
delete p; // Вызовет уничтожение c2, c1, p
Чуть более подробнее можно почитать тут

В вашем случае при выходе из функции Spin память, адресуемая указателем psb будет утеряна, т.е. произойдёт утёчка.
Самый простой способ избежать утечки - избавиться от Spin вовсе и использовать практически канонический hello world
int main() { QApplication a(argc, argv);
QSpinBox psb; psb.show();
return a.exec(); }
Замечу, что в этом случае используется создание QSpinBox на стеке, т.е. деструктор будет вызван автоматически.
Если требуется оставить выделение памяти в куче, то нужно любым доступным образом обеспечить освобождение ресурсов psb при завершении программы.
Один из возможных способов - обернуть его в умный указатель типа QSharedPointer и вернуть наружу из функции:
QSharedPointer Spin() { QSharedPointer psb(new QSpinBox()); psb->show(); return psb; }
Код main будет выглядеть так:
int main(int argc, char *argv[]) { QApplication a(argc, argv); auto s = Spin(); return a.exec(); }
В этом случае при завершении main будет выполнено уничтожение s, который хранит в себе psb

Почему когда ставлю tag в git то он как то отделяется?

Вот работаю на ветке, делаю версию и ставлю таг и он как то отделяется в сторону

version 1.10, 1.11
почему так?
хотя прошлый комит 1.09 нормально выглядит


Ответ

Выглядит так, будто у вас есть три разных коммита с одинаковым сообщением updated gradle version code. Один из них помечен тегом 1.10, но не принадлежит никакой ветке. Другой принадлежит ветке master ⌖, а третий — ветке master 💻 (точнее символов не нашёл). Среди этих двух веток master какая-то ваша локальная (просто master), а какая-то на сервере (origin/master), но иконки этого различия не передают.
Почему такое могло произойти:
Вы дважды переписали один коммит с помощью команды git commit --amend Вы трижды делали коммит с одинаковым названием, а в промежутках откатывались с помощью git reset --soft HEAD^ Инструмент для просмотра истории — глючный, а на самом деле там один коммит.
Что с этим делать?
Пользуйтесь консолью. Не пользуйтесь (глючными) GUI-инструментами. Историю смотрите с помощью git log. Держите удобный alias:
git config --global alias.lg "log --color --graph --abbrev-commit --all \ --pretty=format:'%Cred%h%Creset -%C(yellow ul)%d%Creset %s \ %Cgreen(%cr) %C(bold blue)<%an>%Creset'"
Потом просто:
git lg Коммиты переберите и найдите единственный верный. Как на него переставить тег и origin/master – отдельный вопрос.

Почему alert срабатывает два раза?

В общем загружаем и показываем картинку, скачанную с сервера. Проблема в том, что если сервер возвращает 404, то alert выскакивает 2 раза. Почему?
function view(a) { var img = new Image(); var s = a; myApp.showPreloader('Загружаем...'); img.src = s; img.onload = function() { document.getElementById('showimg').innerHTML = ''; var openPhotoSwipe = function(a) { myApp.hidePreloader(); myApp.allowPanelOpen = false; document.getElementById("check").style.display = "block";
var pswpElement = document.querySelectorAll('.pswp')[0]; var items = [{ src: s, w: img.width, h: img.height }]; var options = { showAnimationDuration: 0, hideAnimationDuration: 0 }; var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options); gallery.init(); gallery.listen('destroy', function() { document.getElementById("check").style.display = "none"; var elements = document.getElementsByTagName("input"); for (var ii = 0; ii < elements.length; ii++) { if (elements[ii].type == "text") { elements[ii].value = ""; } } $$(window).width() < 770 && (myApp.allowPanelOpen = !0); }); }; openPhotoSwipe(); } img.onerror = function() { myApp.alert('Не найдено...'); myApp.hidePreloader(); }}


Ответ

Из-за 404 может генерироваться не одна ошибка. Из-за этого может быть два myApp.alert('Не найдено...');. Как я понял, Ваш код выводит алерт только в случае ошибки, значит - их две.

Как создать шаблонный алиас?

Хочу сделать проверку типа итератора каким-то таким способом:
template using is = std::is_same::iterator_category, T>::value;
И потом использовать это дело в ассертах (RanIt - шаблонный тип):
static_assert(is, "random access required");
Что делаю не так?


Ответ

Либо замените using на constexpr bool, либо уберите из определения ::value и перенесите его в место проверки.
using - не константа, а алиас. Может быть синонимом типа, внутри которого определена константа value, но сам не может быть константой.

Как объединить две кнопки используя if

Есть button Play и button Pause. Хочу объединить их в одну кнопку, чтобы когда композиция уже играет при нажатии ставилась пауза, а если стоит пауза то при нажатии композиция продолжалась. При разных попытках получалась ерунда. Подскажите как объединить.
private void button_play_Click(object sender, EventArgs e) { if ((list_catalog.Items.Count != 0) && (list_catalog.SelectedIndex != -1)) { string current = Vars.Files[list_catalog.SelectedIndex]; Vars.CurrentTrackNumber = list_catalog.SelectedIndex; BassLike.Play(current, BassLike.Volume); label_time1.Text = TimeSpan.FromSeconds(BassLike.GetPosOfStream(BassLike.Stream)).ToString(); label_time2.Text = TimeSpan.FromSeconds(BassLike.GetTimeOfStream(BassLike.Stream)).ToString(); xrewind.Maximum = BassLike.GetTimeOfStream(BassLike.Stream); xrewind.Value = BassLike.GetPosOfStream(BassLike.Stream); timer1.Enabled = true; } }

private void button_pause_Click(object sender, EventArgs e) { BassLike.Pause(); }


Ответ

private bool playing = false;
private void button_Click(object sender, EventArgs e) { if (playing) { BassLike.Pause(); playing = false; return; }
if ((list_catalog.Items.Count != 0) && (list_catalog.SelectedIndex != -1)) { string current = Vars.Files[list_catalog.SelectedIndex]; Vars.CurrentTrackNumber = list_catalog.SelectedIndex; BassLike.Play(current, BassLike.Volume); label_time1.Text = TimeSpan.FromSeconds(BassLike.GetPosOfStream(BassLike.Stream)).ToString(); label_time2.Text = TimeSpan.FromSeconds(BassLike.GetTimeOfStream(BassLike.Stream)).ToString(); xrewind.Maximum = BassLike.GetTimeOfStream(BassLike.Stream); xrewind.Value = BassLike.GetPosOfStream(BassLike.Stream); timer1.Enabled = true; playing = true; } }

Для чего нужен флаг -s в gcc?

Собственно ответ на вопрос я нашел:
Remove all symbol table and relocation information from the executable. (https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options)
Нашел статью о relocation information
relocation information настроечная информация (информация для компоновщика о том, какие конструкции в объектном файле должны быть заменены адресами объектов, определенных в других исходных файлах) (http://computer_en_ru.academic.ru/36046/relocation_information)
Затем нашел ответ на вопрос, что за symbol table такая: https://stackoverflow.com/questions/69112/what-is-a-symbol-table
Но с моим знанием английского целостный взгляд на проблему так и не сложился. Может кто-то поможет собрать все части пазла в единую картину?


Ответ

Компилятор помещает в исполняемый файл не только то, что нужно для запуска (то есть код и данные), но ещё и дополнительную (и в общем-то ненужную) информацию (к примеру, имена всех переменных и функций, включая те, что были объявлены со спецификатором static).
Эта дополнительная информация нужна только на стадии компоновки, но компилятор оставляет её и в конечном исполняемом файле, возможно для удобства дальнейшей отладки. За её вырезание и отвечает флаг -s
Возьмём, к примеру, программу, состоящую из двух файлов исходных кодов:
main.cpp
#include #include
std::string partOne("Hello, "); // Глобальная переменная
std::string getString(); // Прототип функции, объявленной в другом файле
int main() { std::cout << getString() << std::endl; return 0; } other.cpp
#include
extern std::string partOne; static std::string partTwo("World!");
std::string getString() { return partOne + partTwo; } CMake.txt
add_executable(example1 main.cpp other.cpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -flto")
Флаг -flto я вставил для демонстрации того, что даже включение межмодульных оптимизаций не позволяет компилятору убирать какие-либо имена.
Соберём проект в режиме Release (-DCMAKE_BUILD_TYPE=Release) и изучим таблицу символов утилитой nm
004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 00406000 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e4 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e4 b .bss 004063e4 b .bss 004063e4 b .bss 00406020 b .bss 004063e4 b .bss 004063e4 b .bss 004063e8 b .bss 004063e4 b .bss 004063e8 b .bss 004063e4 b .bss 004063e4 b .bss 004063e8 b .bss 004063e4 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e0 b .bss 004063c0 b .bss 00406038 b .bss 004063e8 b .bss 004063e8 b .bss 004063c0 b .bss 004063e8 b .bss 00406080 b .bss 00406078 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 00406078 b .bss 00406044 b .bss 0040606c b .bss 004063e8 b .bss 00406044 b .bss 00406068 b .bss 00406068 b .bss 00406044 b .bss 00406068 b .bss 00406064 b .bss 00406064 b .bss 00406044 b .bss 00406064 b .bss 00406044 b .bss 00406060 b .bss 00406060 b .bss 00406044 b .bss 0040605c b .bss 00406058 b .bss 00406044 b .bss 00406054 b .bss 00406044 b .bss 00406044 b .bss 004063e8 b .bss 00406044 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 004063e8 b .bss 00408000 d .CRT$XCA 00408004 d .CRT$XCAA 00408008 d .CRT$XCZ 0040802c d .CRT$XDA 00408030 d .CRT$XDZ 0040800c d .CRT$XIA 00408010 d .CRT$XIAA 00408014 d .CRT$XIC 00408018 d .CRT$XIZ 0040801c d .CRT$XLA 00408020 d .CRT$XLC 00408024 d .CRT$XLD 00408028 d .CRT$XLZ 00402914 t .ctors 00402918 t .ctors.65535 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403000 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403020 d .data 00403028 d .data 00403028 d .data 00403020 d .data 00403020 d .data 00403004 d .data 00403020 d .data 00403020 d .data 00403028 d .data 00403028 d .data 00403020 d .data 0040301c d .data 00403028 d .data 0040301c d .data 0040301c d .data 00403028 d .data 00403004 d .data 0040301c d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403004 d .data 0040301c d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403018 d .data 00403028 d .data 00403018 d .data 00403028 d .data 00403028 d .data 00403014 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403004 d .data 00403014 d .data 00403028 d .data 00403014 d .data 00403028 d .data 00403004 d .data 00403014 d .data 00403028 d .data 00403014 d .data 00403004 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403028 d .data 00403014 d .data 00403014 d .data 0040300c d .data 00403004 d .data 00403004 d .data 00403008 d .data 00403008 d .data 00403008 d .data 00403004 d .data 00403008 d .data 00403004 d .data 00403004 d .data 00403004 d .data 0040301c d .data 00403028 d .data 00403008 d .data 00403028 d .data 00403028 d .data 00403004 d .data 00403028 d .data$__security_cookie 0040302c d .data$__security_cookie_complement 0040c000 N .debug_abbrev 0040c014 N .debug_abbrev 0040a020 N .debug_aranges 0040a000 N .debug_aranges 0040e000 N .debug_frame 0040b0b3 N .debug_info 0040b000 N .debug_info 0040d077 N .debug_line 0040d000 N .debug_line 004055d8 r .eh_frame 00405298 r .eh_frame 004058a0 r .eh_frame 004053e0 r .eh_frame 00405000 r .eh_frame 0040543c r .eh_frame 004053b4 r .eh_frame 004054d0 r .eh_frame 004052c4 r .eh_frame 0040521c r .eh_frame 00405128 r .eh_frame 00405304 r .eh_frame 00405360 r .eh_frame 00405564 r .eh_frame 004054fc r .eh_frame 004050c8 r .eh_frame 004056b0 r .eh_frame 004058e0 r .eh_frame 00402928 t .gcc_except_table 00407028 i .idata$2 00407000 i .idata$2 0040703c i .idata$2 00407014 i .idata$2 00407184 i .idata$4 00407120 i .idata$4 00407130 i .idata$4 00407128 i .idata$4 004070d0 i .idata$4 00407064 i .idata$4 00407168 i .idata$4 0040714c i .idata$4 004070f4 i .idata$4 0040708c i .idata$4 00407094 i .idata$4 004070f0 i .idata$4 00407104 i .idata$4 00407070 i .idata$4 004070c8 i .idata$4 0040716c i .idata$4 004070cc i .idata$4 004070a0 i .idata$4 00407080 i .idata$4 004070e0 i .idata$4 00407138 i .idata$4 004070fc i .idata$4 00407068 i .idata$4 0040709c i .idata$4 00407124 i .idata$4 0040717c i .idata$4 00407064 i .idata$4 00407140 i .idata$4 004070ec i .idata$4 004070b8 i .idata$4 00407158 i .idata$4 0040712c i .idata$4 004070a8 i .idata$4 00407114 i .idata$4 00407148 i .idata$4 00407108 i .idata$4 0040707c i .idata$4 0040711c i .idata$4 004070b0 i .idata$4 00407118 i .idata$4 00407134 i .idata$4 0040713c i .idata$4 00407174 i .idata$4 00407148 i .idata$4 00407164 i .idata$4 00407078 i .idata$4 004070bc i .idata$4 00407180 i .idata$4 004070e8 i .idata$4 00407170 i .idata$4 00407084 i .idata$4 00407098 i .idata$4 00407178 i .idata$4 00407090 i .idata$4 004070b4 i .idata$4 004070c4 i .idata$4 0040706c i .idata$4 00407088 i .idata$4 004070d4 i .idata$4 00407078 i .idata$4 004070d8 i .idata$4 004070c0 i .idata$4 0040715c i .idata$4 00407150 i .idata$4 004070d8 i .idata$4 00407110 i .idata$4 0040710c i .idata$4 00407154 i .idata$4 004070f8 i .idata$4 00407074 i .idata$4 004070e4 i .idata$4 00407160 i .idata$4 00407100 i .idata$4 004070ac i .idata$4 00407144 i .idata$4 004070dc i .idata$4 004070a4 i .idata$4 004071a0 i .idata$5 004071a8 i .idata$5 004071d0 i .idata$5 004071f0 i .idata$5 00407234 i .idata$5 004071e4 i .idata$5 00407278 i .idata$5 00407274 i .idata$5 004071fc i .idata$5 004071ac i .idata$5 00407224 i .idata$5 00407190 i .idata$5 004071d8 i .idata$5 00407200 i .idata$5 00407208 i .idata$5 004071b4 i .idata$5 004071ec i .idata$5 0040719c i .idata$5 0040729c i .idata$5 004071f8 i .idata$5 004071e0 i .idata$5 00407240 i .idata$5 004071fc i .idata$5 00407238 i .idata$5 00407258 i .idata$5 004071e8 i .idata$5 004072a4 i .idata$5 00407298 i .idata$5 004071f4 i .idata$5 00407288 i .idata$5 00407260 i .idata$5 0040720c i .idata$5 004072a0 i .idata$5 00407188 i .idata$5 00407280 i .idata$5 00407290 i .idata$5 00407250 i .idata$5 004071b0 i .idata$5 004071cc i .idata$5 004071dc i .idata$5 00407284 i .idata$5 0040722c i .idata$5 0040718c i .idata$5 0040725c i .idata$5 00407264 i .idata$5 00407248 i .idata$5 00407204 i .idata$5 00407228 i .idata$5 00407194 i .idata$5 004071c0 i .idata$5 0040728c i .idata$5 00407188 i .idata$5 004072a8 i .idata$5 0040726c i .idata$5 00407254 i .idata$5 00407214 i .idata$5 004071c4 i .idata$5 004071a4 i .idata$5 004071b8 i .idata$5 00407218 i .idata$5 00407270 i .idata$5 0040719c i .idata$5 00407244 i .idata$5 00407198 i .idata$5 0040724c i .idata$5 00407210 i .idata$5 004071d4 i .idata$5 0040726c i .idata$5 0040723c i .idata$5 0040721c i .idata$5 00407220 i .idata$5 004071bc i .idata$5 004071c8 i .idata$5 00407294 i .idata$5 00407268 i .idata$5 00407230 i .idata$5 0040727c i .idata$5 00407724 i .idata$6 00407562 i .idata$6 004074d0 i .idata$6 004076a8 i .idata$6 004075a4 i .idata$6 00407374 i .idata$6 0040738a i .idata$6 004072f4 i .idata$6 00407540 i .idata$6 0040759c i .idata$6 00407708 i .idata$6 004077b8 i .idata$6 004075ae i .idata$6 004074a2 i .idata$6 004072c0 i .idata$6 004074fe i .idata$6 004075c0 i .idata$6 00407610 i .idata$6 004073ec i .idata$6 00407324 i .idata$6 00407580 i .idata$6 004075fa i .idata$6 0040751a i .idata$6 0040735e i .idata$6 00407480 i .idata$6 00407790 i .idata$6 004075c8 i .idata$6 00407494 i .idata$6 004074e0 i .idata$6 004074ee i .idata$6 00407674 i .idata$6 0040756c i .idata$6 00407418 i .idata$6 0040750a i .idata$6 00407592 i .idata$6 00407664 i .idata$6 004076e0 i .idata$6 004072dc i .idata$6 0040730c i .idata$6 00407478 i .idata$6 00407604 i .idata$6 004073d2 i .idata$6 00407740 i .idata$6 004075e6 i .idata$6 004075b6 i .idata$6 004073fc i .idata$6 004075d2 i .idata$6 0040745a i .idata$6 00407634 i .idata$6 00407440 i .idata$6 0040754a i .idata$6 004072ac i .idata$6 004076cc i .idata$6 004075f0 i .idata$6 0040733c i .idata$6 0040734a i .idata$6 004074be i .idata$6 004073c0 i .idata$6 004076f8 i .idata$6 00407578 i .idata$6 004075dc i .idata$6 0040739a i .idata$6 00407684 i .idata$6 004073ae i .idata$6 004077ac i .idata$6 00407430 i .idata$6 0040752c i .idata$6 00407558 i .idata$6 00407588 i .idata$6 00407910 i .idata$7 004078a8 i .idata$7 004078a4 i .idata$7 004078f0 i .idata$7 004078e0 i .idata$7 004078e8 i .idata$7 0040791c i .idata$7 004078dc i .idata$7 0040786c i .idata$7 004078b0 i .idata$7 004078c4 i .idata$7 00407858 i .idata$7 00407820 i .idata$7 0040788c i .idata$7 00407934 i .idata$7 00407870 i .idata$7 004078cc i .idata$7 00407924 i .idata$7 00407898 i .idata$7 00407890 i .idata$7 004078a0 i .idata$7 00407834 i .idata$7 00407928 i .idata$7 004078bc i .idata$7 004078ac i .idata$7 004078c8 i .idata$7 00407848 i .idata$7 0040789c i .idata$7 00407804 i .idata$7 004078d4 i .idata$7 004078b8 i .idata$7 004077fc i .idata$7 00407830 i .idata$7 004078ec i .idata$7 004078d8 i .idata$7 00407874 i .idata$7 00407868 i .idata$7 00407888 i .idata$7 00407930 i .idata$7 0040790c i .idata$7 0040782c i .idata$7 00407828 i .idata$7 00407938 i .idata$7 00407850 i .idata$7 004078c0 i .idata$7 004078f4 i .idata$7 00407908 i .idata$7 00407800 i .idata$7 00407894 i .idata$7 0040781c i .idata$7 00407860 i .idata$7 004078e4 i .idata$7 0040792c i .idata$7 0040784c i .idata$7 004077f8 i .idata$7 0040785c i .idata$7 00407918 i .idata$7 00407920 i .idata$7 004078b4 i .idata$7 00407840 i .idata$7 0040793c i .idata$7 00407824 i .idata$7 00407838 i .idata$7 00407914 i .idata$7 00407808 i .idata$7 00407844 i .idata$7 00407854 i .idata$7 00407878 i .idata$7 0040783c i .idata$7 004078d0 i .idata$7 00407904 i .idata$7 00407900 i .idata$7 00407864 i .idata$7 00403030 d .jcr 00403030 d .jcr 00404064 r .rdata 004041ac r .rdata 00404078 r .rdata 004042ac r .rdata 004042a4 r .rdata 00404074 r .rdata 00404000 r .rdata 00404730 r .rdata$zzz 00404370 r .rdata$zzz 004043b0 r .rdata$zzz 004043f0 r .rdata$zzz 00404430 r .rdata$zzz 00404470 r .rdata$zzz 004044b0 r .rdata$zzz 004044f0 r .rdata$zzz 00404530 r .rdata$zzz 004048f0 r .rdata$zzz 00404570 r .rdata$zzz 004045b0 r .rdata$zzz 004045f0 r .rdata$zzz 00404630 r .rdata$zzz 00404670 r .rdata$zzz 004046b0 r .rdata$zzz 00404930 r .rdata$zzz 004046f0 r .rdata$zzz 004048b0 r .rdata$zzz 004042f0 r .rdata$zzz 00404870 r .rdata$zzz 00404770 r .rdata$zzz 004047b0 r .rdata$zzz 004047f0 r .rdata$zzz 004042b0 r .rdata$zzz 00404830 r .rdata$zzz 00404330 r .rdata$zzz 00404970 r .rdata_runtime_pseudo_reloc 004026d8 t .text 004027d0 t .text 00402390 t .text U .text U .text U .text U .text 004026e0 t .text 00402390 t .text 004027c8 t .text 004027d8 t .text 00402140 t .text 00401500 t .text 00402778 t .text U .text 0040270c t .text 004027d8 t .text 00402140 t .text 00402778 t .text 00402780 t .text 00402000 t .text U .text 004026d0 t .text 00402788 t .text 0040270c t .text 004027d8 t .text 00401f60 t .text U .text U .text 00402790 t .text 00401610 t .text 004027a8 t .text 0040270c t .text U .text 004027c0 t .text 00401f50 t .text 0040270c t .text 00402798 t .text 00401b10 t .text U .text U .text 0040270c t .text 00402798 t .text 00401a50 t .text U .text 0040270c t .text 00402714 t .text U .text 00401a40 t .text U .text 00401a40 t .text 00402720 t .text 004018f0 t .text 004027b8 t .text U .text 004018f0 t .text 00402740 t .text 004018f0 t .text 00402748 t .text 004018f0 t .text 00402750 t .text U .text 00401810 t .text 00402758 t .text 00401810 t .text 00402760 t .text 004017f0 t .text 00402768 t .text U .text 004017e0 t .text 004027b0 t .text 00401000 t .text 00401680 t .text U .text 00402770 t .text U .text 00401700 t .text 00401688 t .text 00401690 t .text 00401690 t .text 004016f8 t .text 00401690 t .text U .text 004016f0 t .text U .text 004016e8 t .text 00401698 t .text 004016e0 t .text 004016a0 t .text U .text 004016d8 t .text 004016a8 t .text 004016d0 t .text 004016a8 t .text 004016c8 t .text U .text U .text 004016c0 t .text 004016b0 t .text 004016b8 t .text 004027a0 t .text 004027e0 t .text.startup 004028f0 t .text.startup 00409004 d .tls 00409000 d .tls$AAA 0040901c d .tls$ZZZ 00000000 A .weak.___deregister_frame_info._hmod_libgcc 00000000 A .weak.___register_frame_info._hmod_libgcc 00000000 A .weak.__Jv_RegisterClasses._hmod_libgcc 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 00000001 a @feat.00 004021c0 T ____w64_mingwthr_add_key_dtor 00402250 T ____w64_mingwthr_remove_key_dtor 004026e0 T ___chkstk_ms 0040800c D ___crt_xc_end__ 00408000 D ___crt_xc_start__ 0040801c D ___crt_xi_end__ 0040800c D ___crt_xi_start__ 0040801c D ___crt_xl_start__ 0040802c D ___crt_xp_end__ 0040802c D ___crt_xp_start__ 0040802c D ___crt_xt_end__ 0040802c D ___crt_xt_start__ 00402910 T ___CTOR_LIST__ 004026d0 T ___deregister_frame_info 00402780 T ___dllonexit 00401f90 T ___do_global_ctors 00401f60 T ___do_global_dtors 00402920 T ___DTOR_LIST__ 00401700 t ___dyn_tls_dtor@12 00401750 T ___dyn_tls_init@12 00404074 R ___dyn_tls_init_callback 004050c8 r ___EH_FRAME_BEGIN__ 004058e0 r ___FRAME_END__ 004015b0 T ___gcc_deregister_frame 00401680 T ___gcc_personality_v0 00401500 T ___gcc_register_frame 00402714 T ___getmainargs 00400000 A ___ImageBase 00403030 d ___JCR_END__ 00403030 d ___JCR_LIST__ 00000000 A ___lconv_init 00401fe0 T ___main 00402630 T ___mingw_enum_import_library_names 00402500 T ___mingw_GetSectionCount 004024b0 T ___mingw_GetSectionForAddress 00401000 t ___mingw_invalidParameterHandler 00406064 B ___mingw_oldexcpt_handler 00408014 D ___mingw_pinit 00401a50 T ___mingw_raise_matherr 00401aa0 T ___mingw_setusermatherr 004022f0 T ___mingw_TLScallback 004063ec B ___mingw_winmain_hInstance 004063e8 B ___mingw_winmain_lpCmdLine 00403000 D ___mingw_winmain_nShowCmd 004063c8 b ___mingwthr_cs 004063c4 b ___mingwthr_cs_init 00402140 t ___mingwthr_run_key_dtors.part.0 00403010 D ___native_dllmain_reason 004063fc B ___native_startup_lock 00406400 B ___native_startup_state 0040300c D ___native_vcclrit_reason 004063f8 B ___onexitbegin 004063f4 B ___onexitend 004026d8 T ___register_frame_info 00401b10 t ___report_error 004020b0 T ___report_gsfailure 00404970 A ___RUNTIME_PSEUDO_RELOC_LIST__ 00404988 R ___RUNTIME_PSEUDO_RELOC_LIST_END__ 00403028 D ___security_cookie 0040302c D ___security_cookie_complement 00402000 T ___security_init_cookie 0040270c T ___set_app_type 00402798 T ___setusermatherr 00401610 t ___tcf_0.lto_priv.6 00401620 t ___tcf_0.lto_priv.7 00401650 t ___tcf_1 004017d0 T ___tlregdtor 00409020 D ___tls_end__ 00409000 D ___tls_start__ 00401180 t ___tmainCRTStartup 00408000 D ___xc_a 00408008 D ___xc_z 0040802c d ___xd_a 00408030 d ___xd_z 0040800c D ___xi_a 00408018 D ___xi_z 0040801c D ___xl_a 00408020 D ___xl_c 00408024 D ___xl_d 00408028 D ___xl_z 00402760 T __amsg_exit 00406414 B __bss_end__ 00406000 B __bss_start__ 00402758 T __cexit 00403004 D __charmax 00403018 D __CRT_MT 00402910 T __CTOR_LIST__ 00403034 D __data_end__ 00403000 D __data_start__ 004017f0 T __decode_pointer 00000000 A __dll__ 00000000 A __dll_characteristics__ 00403008 D __dowildcard 00402920 T __DTOR_LIST__ 00401800 T __encode_pointer 0040a000 D __end__ 00000200 A __file_alignment__ 004023d0 T __FindPESection 00402410 T __FindPESectionByName 00402530 T __FindPESectionExec 0040605c B __fmode 00401f50 T __fpreset 00402898 T __fu0___ZSt4cout 00402720 T __get_invalid_parameter_handler 004025a0 T __GetPEImageBase 004027e0 t __GLOBAL__I_65535_0_objects.a_0xd0.3181 004018f0 T __gnu_exception_handler@4 00407014 I __head_lib32_libkernel32_a 00407028 I __head_lib32_libmsvcrt_a 00407000 I __head_libgcc_s_dw2_1_dll 0040703c I __head_libstdc___6_dll 004072ac I __IAT_end__ 00407188 I __IAT_start__ 00400000 A __image_base__ 0040718c I __imp____deregister_frame_info 004071fc I __imp____dllonexit 00407190 I __imp____gcc_personality_v0 00407200 I __imp____getmainargs 00407204 I __imp____initenv 00407208 I __imp____lconv_init 00407194 I __imp____register_frame_info 0040720c I __imp____set_app_type 00407210 I __imp____setusermatherr 00407214 I __imp___acmdln 00407218 I __imp___amsg_exit 0040721c I __imp___cexit 00407220 I __imp___fmode 00403020 D __imp___get_invalid_parameter_handler 00407224 I __imp___initterm 00407228 I __imp___iob 0040722c I __imp___lock 00407230 I __imp___onexit 00403024 D __imp___set_invalid_parameter_handler 00407234 I __imp___unlock 00407188 I __imp___Unwind_Resume 0040726c I __imp___ZNKSt5ctypeIcE13_M_widen_initEv 00407270 I __imp___ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEc 00407274 I __imp___ZNSo3putEc 00407278 I __imp___ZNSo5flushEv 0040727c I __imp___ZNSs4_Rep10_M_destroyERKSaIcE 00407280 I __imp___ZNSs4_Rep10_M_disposeERKSaIcE 00407284 I __imp___ZNSs6appendERKSs 00407288 I __imp___ZNSsC1EPKcRKSaIcE 0040728c I __imp___ZNSsC1ERKSs 00407290 I __imp___ZNSt8ios_base4InitC1Ev 00407294 I __imp___ZNSt8ios_base4InitD1Ev 00407298 I __imp___ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i 0040729c I __imp___ZSt16__throw_bad_castv 004072a0 I __imp___ZSt4cout 004072a0 I __imp___ZSt4cout 004072a4 I __imp___ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ 00407238 I __imp__abort 0040723c I __imp__calloc 0040719c I __imp__DeleteCriticalSection@4 004071a0 I __imp__EnterCriticalSection@4 00407240 I __imp__exit 00407244 I __imp__fprintf 00407248 I __imp__free 004071a4 I __imp__FreeLibrary@4 0040724c I __imp__fwrite 004071a8 I __imp__GetCurrentProcess@0 004071ac I __imp__GetCurrentProcessId@0 004071b0 I __imp__GetCurrentThreadId@0 004071b4 I __imp__GetLastError@0 004071b8 I __imp__GetModuleHandleA@4 004071bc I __imp__GetProcAddress@8 004071c0 I __imp__GetStartupInfoA@4 004071c4 I __imp__GetSystemTimeAsFileTime@4 004071c8 I __imp__GetTickCount@0 004071cc I __imp__InitializeCriticalSection@4 004071d0 I __imp__LeaveCriticalSection@4 004071d4 I __imp__LoadLibraryA@4 00407250 I __imp__malloc 00407254 I __imp__memcpy 004071d8 I __imp__QueryPerformanceCounter@4 004071dc I __imp__SetUnhandledExceptionFilter@4 00407258 I __imp__signal 004071e0 I __imp__Sleep@4 0040725c I __imp__strlen 00407260 I __imp__strncmp 004071e4 I __imp__TerminateProcess@8 004071e8 I __imp__TlsGetValue@4 004071ec I __imp__UnhandledExceptionFilter@4 00407264 I __imp__vfprintf 004071f0 I __imp__VirtualProtect@16 004071f4 I __imp__VirtualQuery@12 00402768 T __initterm 004025d0 T __IsNonwritableInCurrentImage U __Jv_RegisterClasses 00407878 I __lib32_libkernel32_a_iname 004078f4 I __lib32_libmsvcrt_a_iname 00000000 A __loader_flags__ 00402778 T __lock 00000000 A __major_image_version__ 00000004 A __major_os_version__ 00000004 A __major_subsystem_version__ 00401ab0 T __matherr 0040301c D __MINGW_INSTALL_DEBUG_MATHERR 00000000 A __minor_image_version__ 00000000 A __minor_os_version__ 00000000 A __minor_subsystem_version__ 00406060 B __newmode 004077ac I __nm___ZSt4cout 00401cb0 T __pei386_runtime_relocator 00404988 R __rt_psrelocs_end 00000018 A __rt_psrelocs_size 00404970 R __rt_psrelocs_start 00404970 A __RUNTIME_PSEUDO_RELOC_LIST__ 00404988 R __RUNTIME_PSEUDO_RELOC_LIST_END__ 00001000 A __section_alignment__ 00402730 T __set_invalid_parameter_handler 00401a40 T __setargv 00001000 A __size_of_heap_commit__ 00100000 A __size_of_heap_reserve__ 00001000 A __size_of_stack_commit__ 00200000 A __size_of_stack_reserve__ 00000003 A __subsystem__ 0040901c D __tls_end 00406050 B __tls_index 00409000 D __tls_start 00409004 D __tls_used 00402788 T __unlock 00401688 T __Unwind_Resume 004023b0 T __ValidateImageBase 00402390 t __ValidateImageBase.part.0 00000000 A __Z9getStringv 00406038 b __ZL7partTwo 004016c8 T __ZNKSt5ctypeIcE13_M_widen_initEv 00000000 A __ZNKSt5ctypeIcE8do_widenEc 00401698 T __ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEc 004016e0 T __ZNSo3putEc 004016d8 T __ZNSo5flushEv 004016a8 T __ZNSs4_Rep10_M_destroyERKSaIcE 00401690 T __ZNSs4_Rep10_M_disposeERKSaIcE 004016f0 T __ZNSs6appendERKSs 004016b0 T __ZNSsC1EPKcRKSaIcE 004016f8 T __ZNSsC1ERKSs 004016b8 T __ZNSt8ios_base4InitC1Ev 004016c0 T __ZNSt8ios_base4InitD1Ev 004016e8 T __ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i 004016d0 T __ZSt16__throw_bad_castv 004016a0 T __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ 00406040 b __ZStL8__ioinit 00000000 A __ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_ 004027b8 T _abort 0040601c b _argc 00406010 b _argret 00406018 b _argv 004018d0 T _atexit 004027c0 T _calloc 00404194 r _CSWTCH.5 00000000 A _DeleteCriticalSection@4 00000000 A _EnterCriticalSection@4 00406014 b _envp 00402770 T _exit 00401f50 T _fpreset 004027a0 T _fprintf 004027c8 T _free 00000000 A _FreeLibrary@4 004027a8 T _fwrite 00000000 A _GetCurrentProcess@0 00000000 A _GetCurrentProcessId@0 00000000 A _GetCurrentThreadId@0 00000000 A _GetLastError@0 00000000 A _GetModuleHandleA@4 00000000 A _GetProcAddress@8 00000000 A _GetStartupInfoA@4 00000000 A _GetSystemTimeAsFileTime@4 00000000 A _GetTickCount@0 00406080 b _GS_ContextRecord 004042a4 r _GS_ExceptionPointers 00406360 b _GS_ExceptionRecord 004063e4 b _handler 00406004 b _has_cctor 004063f0 B _hmod_libgcc 00000000 A _InitializeCriticalSection@4 00406078 b _initialized 004063c0 b _key_dtor_list 00000000 A _LeaveCriticalSection@4 00407808 I _libgcc_s_dw2_1_dll_iname 0040793c I _libstdc___6_dll_iname 00000000 A _LoadLibraryA@4 00402850 T _main 004014e0 T _mainCRTStartup 0040600c b _mainret 00402740 T _malloc 00406008 b _managedapp 00401b70 t _mark_section_writable 00406070 b _maxSections 00402750 T _memcpy 00406058 B _mingw_app_type 00402720 t _mingw_get_invalid_parameter_handler 00406054 B _mingw_initcharmax 0040604c B _mingw_initltsdrot_force 00406048 B _mingw_initltsdyn_force 00406044 B _mingw_initltssuo_force 00401810 T _mingw_onexit 00408010 D _mingw_pcinit 00408004 D _mingw_pcppinit 00402730 t _mingw_set_invalid_parameter_handler 004017e0 t _my_lconv_init 00406020 b _obj 00403014 d _p.59329 0040603c b _partOne 00000000 A _partOne 00401010 t _pre_c_init 00401130 t _pre_cpp_init 00000000 A _QueryPerformanceCounter@4 004028f0 t _register_frame_ctor 00000000 A _SetUnhandledExceptionFilter@4 00402790 T _signal 00000000 A _Sleep@4 00406000 b _startinfo 00402748 T _strlen 004027d0 T _strncmp 00406068 b _stUserMathErr 00000000 A _TerminateProcess@8 00406074 b _the_secs 00000000 A _TlsGetValue@4 00000000 A _UnhandledExceptionFilter@4 004027b0 T _vfprintf 00000000 A _VirtualProtect@16 00000000 A _VirtualQuery@12 0040606c b _was_init.60615 004014c0 T _WinMainCRTStartup 004071fc i fthunk 0040719c i fthunk 00407078 i hname 004070d8 i hname
Не кажется, что это как-то слишком много для программы, которая ничего не экспортирует в духе DLL?
Заодно запомним размер программы: 52 105 байт.
Теперь несколько изменим CMakeList.txt
add_executable(example2 main.cpp other.cpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -flto -s")
Мы добавили флаг -s и изменили имя исполняемого файла. Теперь после сборки программы nm выдаёт следующее:
nm: example2.exe: no symbols
То есть программе для работы не требуется ни одно из 1 001 вышеупомянутого имени!
А что с объёмом? 16 896 байт. То есть мы смогли безболезненно уменьшить размер программы в три раза! И это для двух простых объектных файлов. При усложнении же проекта доля имён от размера исполняемого файла будет ещё больше.
Кстати, вы заметили, что бо́льшую часть символов занимают имена секций? Так вот, это следствие различия форматов объектных (ELF) и исполняемых (PE EXE) файлов при сборке под MinGW, не позволяющего объединить эти имена и использовать их по прямому назначению. Также в таблице имён фигурирует большое количество символов из объектных файлов стандартной библиотеки.

При написании данного ответа использовались следующие версии программ:
CMake 3.4.0, GCC 4.9.2 (i686-posix-dwarf-rev1, Built by MinGW-W64 project), GNU nm (GNU Binutils) 2.24.