суббота, 23 апреля 2011 г.

13D LOVES YOU!

Переезд закончен. Сервера застучали своими металлическими сердцами. Песня из бит понеслась по оптическому волокну. Забежала флуоресцентная кровь по системе охлаждения. Заскрипели титановые иглы винчестеров. Залился рассветом восток. Мы снова запустились.

вторник, 22 февраля 2011 г.

Передача строки из C++ в C#

На память (особенно если трюки с char* не принесли должного результата):

С++ dll :

extern "C" __declspec(dllexport) void __stdcall getLongString(char str[], int str_length)
{
   strncpy(str,"long long string",str_length);
   result[str_length-1]='\0';
}

C# app :
[DllImport(“c++_dll_name”, CharSet = CharSet.None)]
public static extern void getLongString(StringBuilder str, int str_length);

public static string get_long_string()
{
   StringBuilder sb = new StringBuilder(260);
   getLongString(sb,sb.Capacity);
   return sb.ToString();
}

Гуд лак!

пятница, 7 января 2011 г.

C++ знакомится с C#

Небольшая памятка, как вызвать с++ unmanaged код из c#.
Создаем dll на плюсах (обычная, не /clr!), где обьявляем экспортируемые функции:
extern "C" __declspec(dllexport) int __stdcall Plus(int a, int b) 
{ 
return a+b; 
}

Далее в шарповом коде создаем небольшой классик, экспортируем функцию и оборачиваем ее для удобства, вот так:

class Wrapper
{
[DllImport("Wrapper.dll")]
static extern int Plus(int a, int b);

public static int plus(int a, int b)
{
try
{
return Plus(a,b);
}
catch (DllNotFoundException e)
{
Console.WriteLine(e.ToString());
}
catch (EntryPointNotFoundException e)
{
Console.WriteLine(e.ToString());
}

return 0;
}
};

Далее использовать функцию следует вот так:
int result = Wrapper.plus(66,11);

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

четверг, 23 декабря 2010 г.

Boost /MD

Чудо батничек на память.

------------------------------

@echo off
echo Build All : static - optimized - /MD
bjam toolset=msvc-9.0 stdlib=native rtti=on inlining=full exception-handling=on optimization=speed variant=release threading=multi link=static runtime-link=shared runtime-debugging=off debug-symbols=off

-------------------------------

Соберет буст в виде статических библиотек с максимальной оптимизацией и опцией MD (link=static runtime-link=shared). Скопировать в .bat файл, положить рядом с bjam (о нем я уже писал).

Соответсвие настроек буста и флагов msvc:

/ML  : runtime-debugging=off runtime-link=static threading=single

/MLd : runtime-debugging=on runtime-link=static threading=single

/MT : runtime-debugging=off runtime-link=static threading=multi

/MTd : runtime-debugging=on runtime-link=static threading=multi

/MD : runtime-debugging=off runtime-link=shared threading=multi

/MDd : runtime-debugging=on runtime-link=shared threading=multi

воскресенье, 28 ноября 2010 г.

понедельник, 12 октября 2009 г.

Извращенные макросы

Довожу Parammix до следующего билда и появилась забавная идея – каким нибудь чудом перегрузить макрос регистрации параметров с возможностью не указывать дефолтные инициализационные значения (например для векторов – конструкции вида REG_PARAMETER(boomer,std::vector<int>()) очень портят настроение.

Итак, покапавшись в разрозненной и очень скудной зарубежной информации по трюкам с макросами прояснилось следующее:

1) переменное количество аргументов достигается с помощью

#define REG_PARAMETER(name,...)       MAKE_PARAMETER(name,__VA_ARGS__)  //для msc

#define REG_PARAMETER(name,args...) MAKE_PARAMETERS(name,args)               //для gcc

2) поменять содержимое макроса можно с помощью игры с комментариями, например такая конструкция

#define FOO(a,...) /**__VA_ARGS__/a/__VA_ARGS__**/

будет выдавать a если нет дополнительных параметров. Разумеется данный макрос неверен, поэтому немного изменим его, для этого обратим внимание на:

3) разграничивать комментарии очень удобно с помощью

#define RR(name) name

 

Перепишем макрос FOO :

#define FOO(a,...) RR(/RR(**__VA_ARGS__)/RR(a)/RR(__VA_ARGS__**)/)

вот так намного лучше, превращать макрос в пустоту при наличии аргументов мы умеем.

 

Теперь задачка посложнее – обратная. Т.е. без аргументов должна оставаться пустая строка, а при наличии аргумента производиться определенное действие – в моем случае инициализация переменной дефолтным значением.

Ход мыслей

- надо выполнить код name=def; при наличии аргумента def

- аргумент def послужит переключалкой

- воображение рисует такую конструкцию /def*/name=def;/**/ – вроде все логично, без аргумента def строка обращается в комментарий, с аргументом – искомую строка становится доступной,  концевой буфер предохраняет нас в обоих случаях. Проблема – не скрывается сам аргумент в –переключателе-.

- приходит мысль модифицировать –переключатель- следующим образом /**def//def*/- данная конструкция скроект аргумент переключатель, осталось собрать все воедино и не забывать про пункт 3 - обратите внимание на двойную косую, может случайно получится комментарий, так что лучше перепишем ее как /RR()/, так безопасней.

- получается такая штука

#define  GOO(a,def) RR(/RR(**def)/RR( )/RR(def*)/RR(name=def;)/RR(**)/)
#define  FOO(a,…) GOO(a,__VA_ARGS__)

Вот такое чудо. Мне пригодилось – надеюсь и вам пригодится. Очень хочу услышать более красивые решения.