Как экспортировать шаблонные функции из dll?
Есть проблема: Загружаю и экспортирую из dll вручную функцию (с помощью GetProcAddress()). Но эта функция шаблонная и я создаю явные специализации.
exports.h
#ifdef API_EXPORT
# define API_EXPORT __declspec(dllexport)
#else
# define API_EXPORT __declspec(dllimport)
#endif
template <class T>
API_EXPORT T sum(T a, T b)
{
return a + b;
}
extern "C" template API_EXPORT int sum(int a, int b);
extern "C" template API_EXPORT float sum(float a, float b); // ERROR LNK1179 (недопустимый или поврежденный файл: повторяющийся COMDAT "_sum")
exports. cpp
#import "exports.h"
template API_EXPORT int sum(int a, int b);
template API_EXPORT float sum(float a, float b);
main.cpp
auto sum = dll.getSymbol<float (*)(float)>("sum");
getSymbol:
void* DynamicLibrary::getSymbol(const std::string& symbolName) const
{
#if PLATFORM == PLATFORM_WIN32
return (void*)GetProcAddress((HMODULE)instance, symbolName.c_str());
#endif
return nullptr;
}
Если использовать extern "C++", то GetProcAddress находит функции по имени, но имена смотрю через банарники и выглядят они страшно). А extern "С" разрешает только одну функцию экспортировать.
Как можно узнать имя функции, которое было сгенерировано, не заходя в бинарникик, или есть ли какой-то другой способ, как можно найти функцию ?
Ответы (1 шт):
Чтобы экспортировать несколько специализаций шаблона для каждой из них необходимо будет придумать уникальное имя (не забывайте идентификаторы в С должны быть глобально уникальными). Чтобы задать эти имена необходимо написать скрипт для линкера в том или инов виде. Для VC++ будет достаточно .def файла.
Но можно сделать и проще - экспортировать не сами специализации, а функцию, предоставляющую эти специализации:
enum t_SpecializationId
{
specialization_int
, specialization_float
...
};
extern "C" void * Fetch_Specialization(t_SpecializationId const id)
{
void * p_result{};
switch(id)
{
case specialization_int:
{
auto const p{&sum<int>};
::std::memcpy(&p_result, &p, sizeof(p_result));
break;
}
...
}
return result;
}