+1
Вобщем-то всем предъявленным требованиям соотвествует SCons.
— написана на Питоне;
— автоматичесий трекинг зависимостей между всеми исходниками, заголовками, и продуктами сборки. Зависимости собирает за один проход без предварительной полной сборки, как это делает make.
— крос компиляция — только указать какой тулчейн использовать.
— независимость сборки модуля от его местоположения в дереве достигается использованием относительных путей (относительно корня дерева, или текущего файла сборки).
— «Модулей» в явном виде нет, поскольку есть автоматический трекинг зависимостей науровне отдельных файлов. А просто группировать файлы можно стандартными средствами Питона.
— из коробки есть поддержка большого количества инструментов: C, C++, C#, Java, D, Fortran и т.д. Даже Zip-ки паковать умеет.
— система зрелая, уже избавившаяся от детских болезней, при этом активно развивается и поддерживатся.

Хотя если хочется написать свой велосиед, то ктож запретит, разработка под микроконтроллеры вообще благодатная почва для них.
  • avatar
  • neiver
  • 09 января 2017, 12:30
+1
Протестировал 5 способ еще раз на всём диапазоне uint32_t. Отклонений не обнаружено.
codepad.org/AZcD1P5Y
  • avatar
  • neiver
  • 26 сентября 2016, 16:57
0
В .NET нет деструкторов, есть финалайзеры. Это концептуально разные вещи, хоть и оба определяются через ~.
Вызов деструктора в С++ как раз детерминирован, в отличии от финалайзера в .NET.
  • avatar
  • neiver
  • 30 мая 2016, 12:08
0
А чем pyserial не устроил для КОМ порта? Кросплатформенный, простой в использовании, дефакто сандарт для дёргания КОМ порта из питонячих скриптов.
  • avatar
  • neiver
  • 16 мая 2016, 10:48
0
Ну почему, во многих скриптовых языках, взять хоть Python или JS — методы там вполне себе объекты первого класса.
  • avatar
  • neiver
  • 14 декабря 2015, 16:39
0
Я не смог найти документального подтверждения этой версии, возможно оно из какого-то кухонного обсуждения с коллегами.
  • avatar
  • neiver
  • 14 декабря 2015, 14:23
0
А зачем передавать указатель на ФЧК в качестве параметра, если можно передавать уже готовый делегат? Это вопрос дизайна интерфейсов.
  • avatar
  • neiver
  • 11 декабря 2015, 13:16
0
Это зависит от calling convention. x86 this обычно передается в регистре ECX (thiscall), а остальные аргументы в стеке, но это зависит от компилятора и его настроек. Если вот так в лоб передать this как обычный аргумент функции, то он вероятно попадет с стек (для stdcall соглашения), а не в ECX.
  • avatar
  • neiver
  • 10 декабря 2015, 17:44
+1
Это очень не надежно. На x86 такое уже не будет работать. Да и на АВР может сломаться в зависимости от настроек компилятора.
  • avatar
  • neiver
  • 10 декабря 2015, 16:23
+2
Разница в том, что когда вызов идет по указателю на ФЧК, в общем случае не известно что за функция вызывается. Это может быть обычная ФЧК, может виртуальная виртуальная, плюс надо учитывать наследование, множественное и виртуальное. Указатель на ФЧК — это хитрая структура с несколькими полями и флагами, размером с два обычных указамеля для GCC и даже больше для некоторых других компиляторов.
Есть неплохая статьяпро указатели на ФЧК и делегаты, где-то были её переводы на русский, если надо.
  • avatar
  • neiver
  • 10 декабря 2015, 14:48
0
Есть мнение, что true метод должен быть «объектом первого класса». Хотя в терминологии как всегда разброд и шатание и где-то исторически сложилось, что функции зовут методами, а где-то наоборот.
  • avatar
  • neiver
  • 10 декабря 2015, 11:00
+1
Одно дело вызывать функцию по обычному указателю на функцию, и совсем другое вызывать функцию член класса(методов в С++ таки нет) по указателю на нее.
У меня в функцию-обёртку InvokeObj указатель на функцию член класса передается как параметр шаблона и известен на этапе компановки. В худшем случае такой вызов будет обычным вызовом по известному адресу, в лучшем — вызов вообще заинлайнится.
  • avatar
  • neiver
  • 09 декабря 2015, 20:11
+2
Я тоже использую подобные делегаты. Несколько рекомендаций:
1. Делегат инициализированный по умолчанию нельзя вызавать — будет доступ по нулевому указателю. Лучше по умолчанию инициализировать делегат пустой функцией, тогда и необходимость проверки отпадет.
2. Нет способа проверить, что делегат пустой и его нельзя вызывать.
3. Вызов функции члена класса по указателю не очень эффективен, порядка 15-30 тактов если без параметров.
4. Чтобы вызвать такой делегат из старого Си-шного кода (а иногда такое надо), придется вручную делать фукнцию обертку.

Есть способ лучше:
#include <iostream>
template<class Result>
class Delegate
{
public:
	typedef Result (*InvokeT)(void *);		// указатель на функцию (Invoke())
	static  Result VoidFunc() { return Result(); }
private:
	void *_object;
	InvokeT _callback;
	template<class ObjectT, Result (ObjectT::* Func)()>
	static Result InvokeObj(void *object){
		return (static_cast<ObjectT*>(object)->* Func)();
	}
	template<Result (* Func)()>
	static Result InvokeFunc(void *){
		return Func();
	}
	Delegate(void *obj, InvokeT func)
		: _object(obj), _callback(func) { }
public:

	Delegate()
		: _object(0), _callback(&InvokeFunc<VoidFunc>)	{ }
	// вызывает конструктор, 
	// для каждой функции класса создаёт свой Invoke (т.к. специализация шаблона!)
	// и передаёт указатель на Invoke как второй параметр ctor"а.
	template<class ObjectT, Result (ObjectT::* Func)()> static Delegate Make(ObjectT * object){
		return Delegate(object, &InvokeObj<ObjectT, Func>);
	}
	template<Result (* Func)()> static Delegate MakeFree(){
		return Delegate(0, &InvokeFunc<Func>);
	}
	// вызов Invoke и передача ему объекта для которого он был создан
	inline Result operator()()const{
		return _callback(_object);
	}
	InvokeT ToCFunction()const{
		return _callback;
	}
	void* Object()const{
		return _object;
	}
};

class Foo
{
public:
	bool Bar(){ std::cout << "Hello" << std::endl; return true;}
};

int main()
{
	Foo foo;
	Delegate<bool> d;
	d();
	d = Delegate<bool>::Make<Foo, &Foo::Bar>(&foo);
	d();
	return 0;
}
  • avatar
  • neiver
  • 09 декабря 2015, 19:17
0
Тут есть ньюансы. Одни пульты при длительном нажатии посылают повторно код кнопки, а другие специальную короткую посылку повтора. Это надо учесть при обработки повторов.
А так ничего сложного: по таймеру (можно програмному) периодически опрашиваем принятый код, если он такой-же как при прошлом опросе, значит повтор.
  • avatar
  • neiver
  • 07 августа 2015, 20:14
0
Очень полезно. Сталкивался с ситуацией, когда подключенный к АЦП операционник с полосой пропускания 5 МГц начинал звенеть с амплитудой напряжения питания при частоте выборок в 1 МГц. Одним лишь RC-фильтром на входе АЦП отделаться не получилось, пришлось еще емкость в обратную связь операционника вводить.
  • avatar
  • neiver
  • 13 июля 2015, 00:31
0
Да, это я с bash-ем попутал, виндовая cmd так не делает.
  • avatar
  • neiver
  • 21 мая 2015, 21:23
0
Надо учитывать, что нотация *.o не избавляет от проблемы слишком длинной командной строки, так как ббрабатывается коммандным процессором и результат записывается в ту-же командную строку, с теми-же ограничениями на длину.
  • avatar
  • neiver
  • 21 мая 2015, 20:05
0
для bare-metal компиляции не нужно проверять зависимости
А если в проекте есть несколько различных типов устройств, использующие общие либы, модульные и интеграционные тесты, которые автоматически собираются и выполняются, загрузчик к которому для каждого из устройств подготавливается образ.
Совсем не нужны зависимости :)
  • avatar
  • neiver
  • 21 мая 2015, 19:47
0
Кроме make есть и другие системы сборки, например, SCons, CMake, qmake, ant, maven и др. И многие из них имеют более приятный синтаксис билд-файлов и богатые возможности чем make.
Я SCons использую для своих проектов и maven на работе.
  • avatar
  • neiver
  • 21 мая 2015, 18:15
0
Сспасибо за дополнения.
  • avatar
  • neiver
  • 09 апреля 2015, 13:30