Страницы

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

Показаны сообщения с ярлыком visual-studio-2010. Показать все сообщения
Показаны сообщения с ярлыком visual-studio-2010. Показать все сообщения

вторник, 25 февраля 2020 г.

Post-build event: Копирование результатов сборки в другую папку

#c_sharp #visual_studio #visual_studio_2010


Есть проект с dll, которую после билда постоянно вручную копирую в нужную папку.
Для автоматизации попробовал указать Post-build event. Просто dll скопировать легко: 
copy $(TargetPath) $(SolutionDir)..\..\lib\

А как за ней утянуть еще и xml описание? Не силен в bat'анике, надо как то отрезать
от $(TargetPath) расширение ".dll" или есть другие способы?    


Ответы

Ответ 1



Visual Studio сама копирует все сборки (dll'ки) и соответствующие им xml файлы в выходную папку, если ваш проект на .NET имеет на них ссылки (References), при этом сложные графы зависимостей резолвятся автоматически. С учетом того, что вы говорите о копировании xml файлов, предположительно, с документацией к сборке, то речь видимо идет о некоторой managed сборке. Таким образом, можно предположить, вы просто неправильно проставили настройки References в вашем проекте, поскольку копирование dll'ок, необходимых для запуска проекта должно происходить автоматически. Файлы с xml документацией по сборкам также копируются автоматически. Если я где-то ошибся в своих предположениях, то могу предложить вам более общее решение. Вместо того, чтобы как-то отрезать от названий файлов расширения и реализовывать некоторую сложную логику в Post-Build Events, сделайте примерно следующее: Определите множество файлов, которые всегда необходимо копировать в папку с собранным приложением (в вашем случае здесь будет дополнительная dll'ка и соответствующий ей xml файл). Отведите для этих файлов специальную папку в вашем проекте. Я в своих проектах использую папки с названиями data и static_data. Семантика этих названий следующая - в data хранятся файлы, без которых запуск приложения или тестов невозможен. Это могут быть какие-то входные данные, файлы для тест-кейсов, какие-то unmanaged dll'ки и т.п. В static_data находятся вспомогательные данные, которые просто используются в проекте - например, графические assets, скетчи UI, важная информация в pdf'ках. Далее в Post-Build Events добавьте следующую команду: xcopy "$(SolutionDir)data\*.*" "$(TargetDir)" /S /E /Y Этим вы гарантируете, что в случае успешной сборки проекта все файлы из data будут скопированы в Output папку с собранным приложением. Есть еще один важный момент, на который стоит обратить внимание - если файлы в папке data обновились, то они, естественно, не будут скопированы в Output до пересборки проекта, а значит, в некоторый момент времени, несмотря на то, что вы уже обновили файлы, собранное приложение будет работать со старым комплектом файлов. Это достаточно критично для тестов.

Ответ 2



Нужны просто немного другие команды в макросе. Вот пример из нашего проекта: copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)....\Export\$(TargetName).dll" copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)....\Export\$(TargetName).xml" точно так же можно добавить и pdb

суббота, 8 февраля 2020 г.

C# Windows Form

#c_sharp #visual_studio #visual_studio_2010


Здравствуйте. 
У меня есть форма в ней есть элементы textBox , richTextBox и кнопка. После ввода
текста в textBox и нажатии на кнопку он форматируется и появляется в richTextBox. После
того как я добавляю окало 10 записей появляется ползунок (т.к. размер элемента не позволяет
вместить в себя их) и текст идет вниз. Чтобы его увидеть нужно каждый раз проматывать
ползунок вниз. Это не совсем удобно. Как сделать так чтобы он проматывался автоматически
вниз после добавления записи?
Заранее спасибо.    


Ответы

Ответ 1



Попробуйте так: mySuperRichTextBox.SelectionStart = mySuperRichTextBox.TextLength; // Курсор в конец текста mySuperRichTextBox.ScrollToCaret(); // И прокручиваемся к курсору

пятница, 31 января 2020 г.

Крашится программа с ассемблерной вставкой

#cpp #c #visual_studio #ассемблер #visual_studio_2010


При выполнении этого кода получаю следующую ошибку:


  Run-Time Check Failure #2 - Stack around the variable 'C' was
  corrupted.


Сам код:

#include 
#include 
#include 

#define SIZE_ROW 1000
#define SIZE_COLUMN 8

#ifndef BYTE
#define BYTE
typedef unsigned char byte;
#endif

void init(byte* A)
{
    for (long long int i = 0; i < (SIZE_ROW * SIZE_COLUMN); i++)
    {
        A[i] = rand() + 5*i + 9;
    }
}

void MyAsm(byte* A, byte* B, byte* C, byte k)
{

    byte lastRes = 0;

    _asm
    {
        pusha

        ;init
        mov ecx, SIZE_ROW*SIZE_COLUMN
        xor esi, esi

    loop1:
        mov bl, byte ptr B[esi]
        mov al, k
        mov dl, byte ptr C[esi]

        imul dl ;k*C
        add al, bl  ;b+k*C

        mov byte ptr A[esi], al
        mov lastRes, al

        inc esi
        loop loop1

        popa
    }

    std::cout << ("Последний результат из ассемблера: " + std::to_string((long long)lastRes));

}

int main() {
    srand(time(NULL));

    byte A[SIZE_ROW * SIZE_COLUMN], B[SIZE_ROW * SIZE_COLUMN], C[SIZE_ROW * SIZE_COLUMN];

    byte k = 2;

    init(B);
    init(C);

    MyAsm(A, B, C, k);

    return 0;
}


При этом если поместить тело функции MyAsm в main(), то всё нормально работает. В
чем может быть ошибка и как ее исправить?  

Компилятор: Microsoft Visual Studio 2010 Professtional
ОС: Windows 10 Pro x64  

Сама задача: вычислить значение выражения A = B + k*C, где k - постоянный коэффециент,
а A, B, C - матрицы одинаковых размеров. При этом нужно сделать через ассемблерную вставку.
    


Ответы

Ответ 1



Инструкции типа mov byte ptr A[esi], al записывают данные в память самой локальной переменной A со смещением esi. То есть это даже близко не является записью в память, указуемую указателем A (как вы, очевидно, хотели). В результате вместо доступа к своим массивам вы разрушаете значение A, а затем и стек вашей функции MyAsm. Чтобы доступиться к памяти массива, переданного через указатель A, вам надо прочитать содержимое A в регистр и адресоваться уже от него. Аналогично со всеми остальными указателями. То есть если делать "в лоб" то например так mov edi, B mov bl, byte ptr [edi + esi] mov edi, C mov dl, byte ptr [edi + esi] ... mov edi, A mov byte ptr [edi + esi], al Разумеется, аккуратно манипулируя регистрами, вы можете избежать постоянного чтения значений A, B и С из памяти.

среда, 29 января 2020 г.

Как установить библиотеку boost?

#boost #cpp #библиотеки #visual_studio_2010


Доброго времени суток. Нужна помощь!

Хочу установить библиотеку boost. Во всех туториалах люди заходят в консольку Visual
Studio Command Prompt (2010). Но проблема в том, что я не могу ее найти! Искать в винде
пробовал - не нашел.

У меня экспресс-версия! Дело в этом?    


Ответы

Ответ 1



Библиотека boost - это набор частично компилируемых исходных кодов. В некоторых случаях ничего не нужно собирать, достаточно скачать с официального сайта дистрибутив, разместить в удобном месте и в настройках проекта указать пути. У меня в специальной папке, где я храню библиотеки многоразового использования, лежит подпапка boost_1_56_0. Рядом с нею еще ряд других более старых версий этой библиотеки. В переменные среды (в windows это там же, где и PATH) я заношу переменную BOOST_ROOT, которая указывает на последнюю сборку. Т.е. как появится новая, я создам папку boost_1_XX_Y и переназначу эту переменную. В настройках любых проектов мне достаточно указать $(BOOST_ROOT)\include - для доступа к headers, и $(BOOST_ROOT)\stage\lib32 / $(BOOST_ROOT)\stage\lib64 для доступа к конкретным библиотекам, нужной мне разрядности. Поскольку boost автоматически выдает имена собираемым библиотекам, с учетом компиляторов, которыми они собираются, даже если у Вас разные компиляторы, бинарники удобно сбрасывать в одну папку, как указано выше. С Intel Compiler у Вас получатся libboost_name-iw-type-version.lib. С Visual Studio у Вас получатся libboost_name-vcXX-type-version.lib, где XX - версия компилятора visual studio (не студии, а именно компилятора). С MinGW с gcc у Вас получится libboost_name-gcc-type-version.lib, если мне не изменяет память. При этом для сборки библиотек, которые необходимо собирать, необходимо выполнить одни и те же действия в консоли: Для Intel Compiler это будет в соответствующем Command Prompt. Для Visual Studio это будет в соответствующем Command Prompt. Для MinGW это будет в обычной консоли, если, конечно, путь к bin в MinGW у Вас добавлен в переменную среды PATH. Действия надо выполнить одни и те же. Сначала bootstrap.bat, а потом b2 --help. В хелпе b2 Вы увидите все варианты настройки сборки, чтобы собрать наиболее удобным Вам образом. Строчка будет выглядеть так: b2 параметр1 параметр2 параметр3 ... toolset - его стоит указать, чтобы сборка производилась конкретным компилятором (gcc, intel, visual studio), причем можно указать и версию компилятора. variant, вид сборки, debug или release. Для разработки Вам понадобятся оба варианта. link - Вы выбираете, будет Ваш бинарный код обращаться в dll или содержать "в себе" все используемые алгоритмы. threading - честно говоря, плохо понимаю смысл этой директивы и всегда указываю multi. Редко мы пишем однопоточные приложения. runtime-link - то же, что и link, только для рантайма. address-model - параметр не указан в хелпе, но помогает выбрать архитектуру собираемых библиотек. stage/install, отличаются лишь тем, что install позволит "выгрузить" только нужное в отдельную папку, stage собирает всё туда, где оно есть. Если Вы не увлекаетесь изменениями исходников boost, stage Вам вполне подойдет. В итоге получается что-то вроде вот такого: b2 toolset=vc120 variant=debug link=shared threading=multi runtime-link=shared address-model=32 stage Для дебага в x32 и такого: b2 toolset=vc120 variant=release link=static threading=multi runtime-link=shared address-model=32 stage Для релиза в x32. Ждете около 40 минут, радуетесь результату. В случае проблем - гуглите, скорее всего уже тысячи людей сталкивались с Вашей проблемой, и ее решение - невнимательность или какие-то специфические настройки чего-нибудь. Например, при сборке boost python вылезает много warning-ов на MinGW из-за конфликта хедеров, подобные вещи можно разрулить в частном порядке. Потратив 2 часа на то, чтобы один раз в этом разобраться, Вы никогда не будете зависеть ни от каких сторонних сборок, будете понимать, где у Вас что лежит, кто туда положил и т.п. В общем, это полезно. ЗЫ: Command Prompt находится в Visual Studio Tools. Или посмотрите в VStudio_PATH\CommonXX\Tools\VsDevCmd.bat

Ответ 2



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

Ответ 3



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

среда, 22 января 2020 г.

Странная ошибка компиляции

#c_sharp #visual_studio #visual_studio_2010


Привет, Хэшкод!
Сегодня натолкнулся на совершенно непонятную ошибку, возникающую при компиляции следующего
кода.
using System;

public class Tree : IComparable>
{
    public int CompareTo(Tuple other)
    {
        return 0;
    }
}


Ошибка при обработке сборки
"Model.dll": Введенное число общих
аргументов не соответствует арности
определения общего типа. Имя
параметра: instantiation

Причём возникает она только в моём проекте. Этот же код в пустом проекте компилируется
успешно. Так же замена Tuple на Tuple да и на множество других параметров
тоже приводит к успешной компиляции.    


Ответы

Ответ 1



Эта ошибка компиляции вызвана багом в фиче Private Accessors в Unit Test Project в старых версиях студии. Падает на стадии постпроцессинга сборки, при попытке сгенерировать аццессоры для приватных свойств класса Tree, или для классов, использующих Tree. Этот баг в connect - won't fix. Фича Private Accessors не поддерживается еще со времен 2010-й студии, так что если вы ее еще испльзуете - самое время пересмотреть архитектуру и перейти на моки для тестирования.

воскресенье, 14 апреля 2019 г.

C# Windows Form

Здравствуйте. У меня есть форма в ней есть элементы textBox , richTextBox и кнопка. После ввода текста в textBox и нажатии на кнопку он форматируется и появляется в richTextBox. После того как я добавляю окало 10 записей появляется ползунок (т.к. размер элемента не позволяет вместить в себя их) и текст идет вниз. Чтобы его увидеть нужно каждый раз проматывать ползунок вниз. Это не совсем удобно. Как сделать так чтобы он проматывался автоматически вниз после добавления записи? Заранее спасибо.


Ответ

Попробуйте так: mySuperRichTextBox.SelectionStart = mySuperRichTextBox.TextLength; // Курсор в конец текста mySuperRichTextBox.ScrollToCaret(); // И прокручиваемся к курсору

вторник, 2 апреля 2019 г.

Крашится программа с ассемблерной вставкой

При выполнении этого кода получаю следующую ошибку:
Run-Time Check Failure #2 - Stack around the variable 'C' was corrupted.
Сам код:
#include #include #include
#define SIZE_ROW 1000 #define SIZE_COLUMN 8
#ifndef BYTE #define BYTE typedef unsigned char byte; #endif
void init(byte* A) { for (long long int i = 0; i < (SIZE_ROW * SIZE_COLUMN); i++) { A[i] = rand() + 5*i + 9; } }
void MyAsm(byte* A, byte* B, byte* C, byte k) {
byte lastRes = 0;
_asm { pusha
;init mov ecx, SIZE_ROW*SIZE_COLUMN xor esi, esi
loop1: mov bl, byte ptr B[esi] mov al, k mov dl, byte ptr C[esi]
imul dl ;k*C add al, bl ;b+k*C
mov byte ptr A[esi], al mov lastRes, al
inc esi loop loop1
popa }
std::cout << ("Последний результат из ассемблера: " + std::to_string((long long)lastRes));
}
int main() { srand(time(NULL));
byte A[SIZE_ROW * SIZE_COLUMN], B[SIZE_ROW * SIZE_COLUMN], C[SIZE_ROW * SIZE_COLUMN];
byte k = 2;
init(B); init(C);
MyAsm(A, B, C, k);
return 0; }
При этом если поместить тело функции MyAsm в main(), то всё нормально работает. В чем может быть ошибка и как ее исправить?
Компилятор: Microsoft Visual Studio 2010 Professtional ОС: Windows 10 Pro x64
Сама задача: вычислить значение выражения A = B + k*C, где k - постоянный коэффециент, а A, B, C - матрицы одинаковых размеров. При этом нужно сделать через ассемблерную вставку.


Ответ

Инструкции типа
mov byte ptr A[esi], al
записывают данные в память самой локальной переменной A со смещением esi. То есть это даже близко не является записью в память, указуемую указателем A (как вы, очевидно, хотели). В результате вместо доступа к своим массивам вы разрушаете значение A, а затем и стек вашей функции MyAsm
Чтобы доступиться к памяти массива, переданного через указатель A, вам надо прочитать содержимое A в регистр и адресоваться уже от него. Аналогично со всеми остальными указателями.
То есть если делать "в лоб" то например так
mov edi, B mov bl, byte ptr [edi + esi] mov edi, C mov dl, byte ptr [edi + esi] ... mov edi, A mov byte ptr [edi + esi], al
Разумеется, аккуратно манипулируя регистрами, вы можете избежать постоянного чтения значений A, B и С из памяти.