Экспорт шаблона в функцию C

0

Я создаю привязки Haskell для библиотеки C. Тем не менее, я хочу адаптировать вызывающие соглашения библиотеки к чему-то более подходящему для Haskell, поэтому я создал класс шаблонов, который имеет статический метод, который вызывает правильный метод, когда вы используете его следующим образом:

Wrap<decltype(&libraryFunction), &libraryFunction>::call(...);

Где ... обозначает аргументы. Это здорово, компилятор создал для меня код оболочки. Я даже могу взять адрес этой функции с помощью оператора & поэтому, по-видимому, это просто регулярная функция.

Тем не менее, Haskell не может использовать шаблоны C++, поэтому я хотел бы явно создать этот шаблон для требуемых функций и экспортировать их как обычную функцию C, которую я могу ссылаться на Haskell. Я знаю, что могу просто сделать заглушки, которые вручную вызывают эту статическую функцию-член, но пусть говорят, что мне это действительно не нравится.

Есть идеи, как это сделать? Портативный или не портативный, я хотел бы знать, если это возможно.

  • 1
    Каким будет название функции?
  • 0
    Вы пробовали extern "C" ?
Показать ещё 6 комментариев
Теги:
c++11
templates
shared-libraries

1 ответ

2

Это невозможно сделать портативно:

[Temp]/4

Шаблон, явная специализация шаблона и частичная специализация шаблона шаблона не должны иметь C-ссылки.

Обратите внимание, что это также мешает вам использовать указатель на эту функцию, позволяя Haskell вызывать функцию через этот указатель: не гарантируется, что, например, соглашение о вызове функции C++ (в программе C++) совпадает с Haskell предполагает для указателя функции, который он получает.

Что можно сделать портативно - это экспортировать одну внешнюю функцию extern "C" которая переводит между языковыми связями между C и C++. Вы можете передавать указатели функций или другие типы идентификаторов в Haskell, а Haskell называет эту единственную функцию C, передающую идентификатор функции, которую он фактически хочет вызвать:

std::map<int, void(*)(int32_t)> functions;

extern "C" interface_fct(int id, int32_t arg)
{
    functions[id](arg);
}

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

Вы можете написать что-то похожее на va_args (но более безопасное), чтобы передать произвольные аргументы, но было бы более полезно писать что-то непереносимое.

  • 0
    Я был довольно уверен, что это нельзя сделать мобильно, поэтому я искал что-то непереносимое. В любом случае это не имеет значения, поскольку рассматриваемая библиотека является системной библиотекой OS X.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню