Название: Глобальные переменные в чужом API Отправлено: kramer от Декабрь 24, 2012, 12:47 Здравствуйте, друзья!
Прошу помощи коллективного разума. Проблема вот в чем: есть некий довольно замшелый API, древность которого не отменяет необходимости его использовать. Среди прочего он позволяет определять контролы на форме путем определения глобальных переменных-структур вида Код: extern "C" StructIntType StructInt27 = { Сами структуры StructIntType и прочие определены в заголовочном файле - по одной на каждый тип контрола. Имя глобальной переменной при этом строго фиксировано, Int в имени позволяет хост-приложению определить тип моего контрола, а 27 - его место в сетке на форме (нет, это не я придумал, из-звините). Соответственно, в коде этот контрол используется по этому имени а-ля StructInt27.Value = SomeValue;. Не очень удобно, не правда ли? Вопрос, собственно, в том, как это хозяйство привести к более-менее удобоваримому виду. Требований, по сути, два - контрол должен определяться в одном месте (одним вызовом функции или макроса), и при этом для него должно вводится некое осмысленное имя, по которому до него можно будет достучаться из других модулей компиляции. ОС - Линукс, компилятор - gcc/g++ 3.4. Спасибо. Название: Re: Глобальные переменные в чужом API Отправлено: ssoft от Декабрь 24, 2012, 15:25 А не используется ли вдобавок ко всему описанному какие-нибудь шаги предкомпиляции.
Другими словами, какой механизм обработки номера места в сетке на форме? А так, могу предложить что-то вроде набора макросов типа Код:
Название: Re: Глобальные переменные в чужом API Отправлено: kramer от Декабрь 24, 2012, 16:31 А не используется ли вдобавок ко всему описанному какие-нибудь шаги предкомпиляции. Спасибо за ответ. Все гораздо проще, чем вы думаете, хост-приложение просто смотрит на все экспортируемые символы моего DSO, и, если находит символ, подходящий по шаблону вида Struct{Int|Float|etc}{0..121}, то считает, что это контрол соответствующего типа в соответствующей ячейке сетки на форме. Другими словами, какой механизм обработки номера места в сетке на форме? Ваш подход первым приходит в голову, но есть закавыка - поскольку присутствует инициализатор, компилятор будет считать, что это определение символа, и соответственно при включении в несколько исходных файлов возникнет конфликт глобальных имен. Я выкрутился пока так: в отдельном заголовочном файле ControlMacros.h я определяю каждый такой макрос в зависимости от условия #ifdef __CONTROL_UNIT. В первом случае он буквально совпадает с вашим (только позиция вынесена в аргумент, и нет последней строчки), а во втором - как раз объявление этой структуры как extern и указателя по имени MyCtrlName (в моем случае, функции) на нее. Затем, скажем, в еще одном заголовочном файле Controls.h я с помощью этого условного макроса определяю все контролы, которые мне понадобятся, и наконец при включении Controls.h в один из исходных файлов, например, Controls.cpp, я ПЕРЕД включением определяю __CONTROL_UNIT, и вуаля - в этом и только в этом файле определяются экспортируемые символы, а во всех остальных, куда включается Controls.h - только их декларации и ссылки/функции с осмысленными именами. Вот такой вот изврат, может кому пригодится. |