По некоторым причинам у меня есть довольно много функций разделяемой библиотеки, написанной на C ++, которые должны быть «обернуты» C-функцией для правильного вызова. Теперь мне интересно, смогу ли я автоматизировать этот процесс (в лучшем случае хорошо интегрированный в мой CMake-build-process)
Пример: предположим, у меня есть определение функции
extern "C" void foo(Somestruct myinfo, char const * const data, char const * const data2)
в моем .hpp-файле. Теперь я бы изменил это определение, скажем,
C_WRAPPER void foo(Somestruct myinfo, ARG(1) data, ARG(3) data2)
Используя некоторые макросы, это можно без проблем преобразовать в исходную форму — таким образом, оставив hpp-файл нетронутым с функциональной точки зрения.
Некоторый парсер теперь должен прочитать этот файл и создать новый c-файл, который содержит (например)
extern void foo(Somestruct myinfo, char const * const, char const*const);
void foo_wrapper(Array everything) {
char * data1 = fromArray(array, 1);
char * data3 = fromArray(arary, 3);
foo(fromArray(0), data1, data3);
}
Граничные условия: общая схема всегда выглядит одинаково. Разница лишь в том, что количество ARG
s обязательно постоянен. Аргументы ARG
укажите позицию в массиве, в котором находятся данные.
В настоящее время файл оболочки написан вручную, что привело к некоторым трудоемким ошибкам из-за изменений интерфейса в прошлом. Вот почему я хотел бы автоматизировать этот шаг.
Вы знаете способ архивировать что-то подобное без необходимости создавать парсер самостоятельно? Как уже было сказано, желательно то, что хорошо вписывается в мой процесс сборки с использованием CMake.
Я имею честь ответить на свой вопрос.
Это можно сделать полностью в CMake.
Вот только скрипт CMake, который заполняет переменную funcstring
который содержит все функции оболочки. Используя типичный файл конфигурации, эти строки могут быть записаны в функции оболочки.
set(sources a.cpp)
foreach(source ${sources})
file(READ ${source} contents)
foreach(var IN ITEMS ${contents})
string(REGEX MATCH "C_WRAPPER[ ]+[a-zA-Z0-9]+[(].*[)]" wrapperfun ${var})
if(wrapperfun)
string(REGEX REPLACE "C_WRAPPER[ ]+\([a-zA-Z0-9]+\)[(].*[)]" "\\1" function_name ${wrapperfun})
string(REGEX MATCHALL "ARG[(][0-9]+[)]" args ${wrapperfun})
set(lines "")
set(funcargs "")
foreach(arg ${args})
string(REGEX MATCH "[0-9]+" num ${arg})
set(lines "${lines}
char * data${num} = fromArray(array, ${num})\;")
set(funcargs "${funcargs}, arg${num})")
endforeach(arg)
set(funcstring "${wrapperfun}\;
Datum ${function_name}_wrapper(Array everything) {
${lines}
return ${function_name}(fromArray(0), ${funcargs})\;
}
")
endif()
endforeach(var)
endforeach(source)
Макросы не были заменены — это можно сделать в CMake, но это более короткий и простой способ включить адекватные определения макросов в окончательный C-файл.
Других решений пока нет …