Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dllexport function with templates (C++)

Tags:

c++

templates

dll

I would like to know whether it is possible to define a templated dllexport function. Until now the function was not templated, and it is working properly. The code was this:

module.cpp:

#if defined(__cplusplus)
    #define DLL_Export extern "C" __declspec(dllexport)
#else /* __cplusplus */
    #define DLL_Export __declspec(dllexport)
#endif /* __cplusplus */
...
VirtualTPM * virtual_tpm;
...
DLL_Export void TestPointModule_Check(string name, void * value){
    virtual_tpm->CheckTestPoint(name, value);   
}

However, I need to extend the TestPointModule_Check function to manage other datatypes, so I created a templated CheckTestPoint(...) function, and I tried this:

module.cpp:

...
template <typename T>
DLL_Export void TestPointModule_Check(string name, void * value){
    virtual_tpm->CheckTestPoint<T>(name, value);    
}

but this gives me the following error: error C2988: unrecognizable template declaration/definition

The VirtualTPM::CheckTestPoint<T> is correctly defined, since I can call a virtual_tpm->CheckTestPoint<int>(name, value); without errors.

Is there a possible way to do what I need? I would be able to restrict the template to 4 different datatypes (in fact, I did this when defining the template for the VirtualTPM::CheckTestPoint<T> function, but I don´t know how to do it.

like image 916
Iban Avatar asked Oct 30 '13 13:10

Iban


3 Answers

Templated functions does not exist until they are instantiated. So that means that you can export only its instances not the template itself.

But you if you put the template definition in a header you can normally use it in other projects - same as you would do for header-only libs.

Edit: Untested sample (this should export the function from DLL):

module.h:

template <typename T>
DLL_Export void TestPointModule_Check(string name, T * value);

module.cpp:

template <typename T>
DLL_Export void TestPointModule_Check(string name, T * value){
  virtual_tpm->CheckTestPoint<T>(name, value);    
}

// explicit instantiation
template void TestPointModule_Check<SomeType>(string name, SomeType * value);
like image 133
Johny Avatar answered Oct 21 '22 07:10

Johny


Not sure whether the other answers work, but I could not make them work. This is what should be done, with an example (the function template can generalize to any kind of template function):

In *.hpp:

template <typename T>
int randomFunction(T templateElement);

In *.cpp:

template <typename T>
int randomFunction(T templateElement)
{
    // code...
}
template DLL_EXPORT_IMPORT int randomFunction(float templateElement);
template DLL_EXPORT_IMPORT int randomFunction(double templateElement);
// Any other types you wanna implement...

And where DLL_EXPORT_IMPORT should be defined once in your library as something like:

#ifndef _WIN32
    #define DLL_EXPORT_IMPORT
#elif defined OP_EXPORTS
    #define DLL_EXPORT_IMPORT __declspec(dllexport)
#else
    #define DLL_EXPORT_IMPORT __declspec(dllimport)
#endif
like image 2
Ginés Hidalgo Avatar answered Oct 21 '22 07:10

Ginés Hidalgo


In addition to what @Jhonny already pointed out You should be able to say:

...
template <>
DLL_Export void TestPointModule_Check<AParticularType>
                    (string name, AParticularType* value) {
    virtual_tpm->CheckTestPoint<AParticularType>(name, value);  
}

Put to header:

template<typename T>
void TestPointModule_Check(string name, T* value);

and:

template <>
DLL_Export void TestPointModule_Check<AParticularType>
                    (string name, AParticularType* value);

Also overwork your macro definitions to export from c++:

#if !defined(__cplusplus)
//  ^ Note
#define DLL_Export extern "C" __declspec(dllexport)
#else /* __cplusplus */
#define DLL_Export __declspec(dllexport)
#endif /* __cplusplus */

To find additional information about the topic refer to this link or this one.

like image 1
πάντα ῥεῖ Avatar answered Oct 21 '22 06:10

πάντα ῥεῖ