Ответы пользователя по тегу C++
  • С++ Классы, нужно сравнить два объекта одного класса и вывести результат на экран, как это сделать?

    @tomatho
    Как? Решительно, стремительно!
    Если этот код писали вы - то не составит труда.
    Если это задание в курсе лекций - то я не намерен помогать изображать фальшивое понимание.
    Ответ написан
    3 комментария
  • Где взять готовые графические решения для разработки приложения на WinAPI?

    @tomatho
    WinAPI же не о GDI.
    Просто используйте стандартные элементы.
    Написание кастомных элементов всегда было попо-болью.

    Мне вот щас бы пригодился кастомный edit, но прогуглив целый день, я узнал, что "простых" решений нет, только написание с нуля.
    Ответ написан
    Комментировать
  • Не работают точки останова, в чем может крыться причина?

    @tomatho
    Иди в модули, и проверяй подключились ли символы.
    Debugger->Windows->Modules (по памяти пишу, мб не там)
    Суть: там список всех dll с пометками symbols loaded / not found и возможностью посмотреть подробности.

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

    Не знаю на счёт CLI но у C++ ещё может быть проблема с rebase.
    Если exe/dll загрузился не по его обычному Base Address, то символы тоже могут не работать,
    это решается добавкой в настройке проекта насильно другого Base Address по умолчанию.
    Для exe не загрузится по обычному Base Address это редкость, а вот для dll обычное дело.

    Так же, у меня была проблема с отладкой обычной C++ dll именно из-за того, что я вместо тулсета самой 2015 студии, выбрал тулсет 2010-й студии. Breakpoint-ы из-за этого не работали.
    В таком случае можно отлаживать под 2015, а собирать Release под нужным вам тулсетом.
    Ответ написан
  • Как посчитать центр тяжести человека используя Kinect?

    @tomatho
    Если требуется приблизительно предположить местоположение центра масс исходя из табличных данных которые мы предполагаем весят данные части тела, то ваша формула для координаты x верна, а для всех остальных координат аналогично.
    Но это только если у всех x одна общая система координат, и эти координаты должны быть центрами масс частей тела, и тогда центр масс тоже будет в этой же системе координат.

    На всякий случай, вдруг пригодится, если вы не знали, простая формула для середины отрезка:
    x = (x1 + x2)/2
    y = (y1 + y2)/2
    z = (z1 + z2)/2

    Применительно к кинекту ничего не знаю. Думаю массы по координатам частей тела тоже можно определить приблизительно, если есть существенная выборка и исходя из гипотезы, что чтобы не упасть человеку нужно удерживать центр масс в некоторой области под собой. Но это слишком сложно, и сомневаюсь в целесообразности этого.
    Ответ написан
    Комментировать
  • C++. Как происходит возвращение локального объекта функциями?

    @tomatho
    Для локальных переменных всегда вызывается деструктор, поэтому есть техники использования этого свойства для некоторых нужд, типа лока мьютекса в конструкторе, и анлока в деструкторе.

    Обычные указатели хранят адрес. Для обычных указателей деструктор ничего не делает.
    А вот если локальная переменная представляет из себя не указатель, или умный указатель, то в его деструкторе может что-то быть, тем самым объект может высвободить память, либо произвести какие-либо другие манипуляции.

    Умные указатели позволяют более гибко управлять памятью. (shared_ptr, unique_ptr...)
    Они с технической точки зрения ничем не отличаются от обычных классов (структур).
    Им просто заранее ради вашего удобства написали подходящие реализации конструкторов, деструкторов, и других операторов.

    После высвобождения памяти адрес не перестаёт быть адресом, поэтому все манипуляции остаются возможными, кроме чтения и записи. Это уже как повезёт. Другое дело, что это не нормальное поведение - читать / писать высвобожденную память. Она уже может быть занята чем-то другим, либо изменена.

    Поэтому: никогда не возвращайте ни ссылки, ни адреса локальных переменных, за исключением тех, которые по факту глобальные: например те, которые объявлены как static.
    Однако такая static переменная находится в единственном экземпляре, а значит к ней нельзя будет одновременно обратиться из нескольких потоков. Точнее можно, но это не нормально, приведёт к ошибкам.

    Ах да, забыл ответить на заголовок.
    Точно не знаю, сначала опишу как можно это понимать, а потом уже укажу какую точность не знаю.

    Можно это понимать так: вы объявляете в вызывающей функции (caller) локальную переменную, и потом результат вызова присваиваете этой переменной. Эта переменная находится в стеке вызывающей функции (caller).
    В функции которую вы вызываете (callee) тоже есть локальная переменная результата.
    И после того как вызов закончился, caller присваивает результат от callee через оператор копирования.
    То есть
    1. Конструктор переменной в которую будет возвращён результат в функции из которой происходит вызов (caller). Кроме случая когда вызов является одним из параметров конструктора.
    2. Конструктор результата в функции которая вызвана (callee)
    3. Манипуляции с результатом (если есть таковые)
    4. Оператор копирования, кроме случая когда вызов является одним из параметров конструктора.

    Что за конструктор с параметром вызова? Ну например так:
    #include <string>
    int meaning_of_life()
    {
      return 42;
    }
    
    std::string wat()
    {
      return "wat"; // тут будет вызван std::string("wat")
    }
    
    int main()
    {
      int a(meaning_of_life()); // тоже самое, что и int a = meaning_of_life();
      std::string s(wat()); // тоже самое, что и std::string s = wat();
      return 0;
    }

    В таком случае результат используется прямо в конструкторе, поэтому оператор копирования не нужен. В таком случае конструктор называется конструктором копирования.

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

    И наконец: ссылки ничем не отличаются от указателей в техническом плане. Это просто синтаксический сахар.

    Поправьте меня если я где-либо не прав. Буду рад.
    Ответ написан
  • Как решить проблему с dll?

    @tomatho
    Дело в том, что у тебя в C++ так называемый unmanaged code.
    Проще всего его вызвать как-то так:
    using System.Runtime.InteropServices;
    
    [DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall)]
    public static extern int Card();

    При этом Assembly.Load не нужен. Потому что он для managed. Reflection как бы намекает.
    Можно ещё обернуть в C++ так чтобы он стал managed, но это лучше гугл.
    Поля этих ответов слишком узкие чтобы это вместить, да и я не знаю деталей.

    Пока не забыл: битность dll должна совпадать с битностью приложения.

    В MSDN написано, что System.BadImageFormatException может быть если не указан /fixed:no при компиляции.
    Ответ написан
    Комментировать
  • Как подключит стороннюю ,dll в VS?

    @tomatho
    Ваша pragma нужна если вы статически линкуетесь с библиотекой, то есть, dll после этого не понадобится. (кроме нестандартных случаев)
    вместо pragma можно в свойствах проекта, во вкладке C++->Linker->Input->Additional Dependencies прописать путь к .lib

    Важно: если библиотека линкуется статически (через .lib), то LoadLibrary() не нужен!
    LoadLibrary нужен для динамической загрузки .dll
    Однако если LoadLibrary() вызван на уже подгруженной .dll он всё же должен вернуть HMODULE.

    И да, воспользуйтесь CFF Explorer, может подгружаемая вами .dll не может найти свои зависимости.
    Для этого зайдите во вкладку Dependency Walker.
    И как уже верно сказали: 32-битная версия программа не может работать с 64-битными библиотеками, вообще не может. Аналогично 64-битные программы не могут работать с 32-битными библиотеками. Вообще не могут.
    Ответ написан
    Комментировать