Kamailio: Пишем модуль на C++

Прошло уже больше года, как я собирался написать модуль на C++ для Kamailio. По моему самое время все такие пролить свет и продолжить серию статей о Kamailio: установка и написание модуля. Единственное, по пришествию этого года - только второстепенный модуль был написан на С++. Как показала практика, лучше писать библиотеку - ее тестировать и подключать к Kamailio. Но тем не менее, случаются и исключения, так что добро пожаловать под капот.

Написание модуля для С++ дает некоторые преимущества:
  • библиотек с API на С++
  • контейнеров и алгоритмов из STL ( включая использование в shared memory )
  • templates и классы

Что использовать нельзя ни в коем случае - это потоки, надеюсь объяснять почему не нужно.

Время прошло достаточно много с последней статьи, поэтому начнем с нуля, но кратко ( подробно ):
  • Качаем kamailio-4.3.1_src.tar.gz
  • sudo apt-get install bison flex
  • tar -xvf kamailio-4.3.1_src.tar.gz && ln -sf kamailio-4.3.1 kamailio && cd kamailio

Теперь будем внедрять поддержку С++, правим Makefile.sources ( в стиле diff ):

--- Makefile.sources  2015-08-29 18:59:58.546686366 +0300
+++ Makefile.sources.cpp      2015-08-29 18:59:39.322591034 +0300
@@ -10,7 +10,7 @@
 # defines: sources, objs, depends
 #

-sources=$(filter-out $(auto_gen), $(wildcard *.c) $(wildcard mem/*.c) \
+sources=$(filter-out $(auto_gen), $(wildcard *.cpp) $(wildcard *.c) $(wildcard mem/*.c) \
    $(wildcard parser/*.c) $(wildcard parser/digest/*.c) \
    $(wildcard parser/contact/*.c) $(wildcard db/*.c) \
    $(wildcard parser/sdp/*.c) \
@@ -19,9 +19,10 @@
 ifeq ($(CORE_TLS), 1)
  sources+= $(wildcard tls/*.c)
 endif
-objs=$(sources:.c=.o)
+sources_basenames=$(basename $(sources))
+objs=$(addsuffix .o,${sources_basenames})
 extra_objs=
-depends=$(sources:.c=.d)
+depends=$(addsuffix .d,${sources_basenames})
 cmodules=
 static_modules=
 static_modules_path=

И еще одни файл Makefile.rules, просто дублируем секцию, меняя c на cpp:

#implicit rules
%.o:%.c  $(ALLDEP)
  $(call exec_cmd,CC)
  @$(call cmd_MKDEP)

#implicit rules
%.o:%.cpp  $(ALLDEP)
  $(call exec_cmd,CC)
  @$(call cmd_MKDEP)

Ну вот и все теперь приступим к созданию модуля.

Возьмем за основу модуль который описан в предыдущей статье, просто изменив исходник на cpp:

modules/my_module
├── Makefile
└── my_module.cpp

А вот в Makefile нужно еще будет добавить строчки:

DEFS+=-D_GNU_SOURCE -fpermissive
LIBS += -lrt -lstdc++

Да, и не забываем обернуть include в extern "C":

extern "C" {
#include "../../sr_module.h"
}
Ну вот и все, можно собирать, но будет куча warning'ов:
  • make PREFIX=$KAM_PREFIX install_modules="my_module" cfg all install
  • Запускаем
./int/sbin/kamailio -DD -w $KAM_PREFIX -f p.cfg

В результате вроде поддержка и есть, но что-то это не выглядит как С++, а вот чтобы получить profit надо сделать framework, и об этом следующая статья.