KeetL
asked on
Using a template for an internal method only
Is it possible to use a template for an internal method "only" without defining the class to be a template class itself....
My Compilers (M$VC6,gcc,cxx) don't seem to think so. They all compile but have trouble finding the method signature during link time.
class LibLoader
{
public:
static LibLoader* Instance ();
bool doesLibExist (const char* libName) const;
TLIB_ID loadLib (const char* libName);
bool unLoadLib (TLIB_ID libID);
template <typename T>
T loadSymbol (const char* symbolName, TLIB_ID libID,T a) const;
}
As you can probably tell the class is a dynamic library loader which is also a singleton.
The original problem stemed from loading the symbol to a correct type (void*) -> (definable function pointer). I achieved this easily with a simple template function however my efforts to clean it all up and put it in the class are proving problematic.
This is what i would ideally like to have....
//load library
TLIB_ID libID = LibLoader->loadLib("msvcrt .dll");
// define symbol type
typedef int (*myFunctionType)(const char*);
// create a variable for use
myFunctionType a = 0;
// load the symbol with the help of a template method nested inside a non-templated class
a = LibLoader->loadSymbol("ato i",libID,a );
I32 x = a("1234");
This is what works for now with the help of the templated function FuncEntry(.....) as defined below
template <class T>
T FuncEntry(T a,void *vEntry)
{
long lEntry = ACE_reinterpret_cast (long, vEntry);
return ACE_reinterpret_cast (T, lEntry);
}
void *entry;
typedef int (*myFunctionType)(const char*);
myFunctionType a = 0; // just to initialise b 4 use
TLIB_ID libID = LibLoader->loadLib("msvcrt .dll");
entry = LibLoader->loadSymbol("ato i",libID);
a = FuncEntry(a,entry);
int x = a("1234");
/////////////////////////\ \\\\\\\\\\ \\\\\\\\\\ \\\\\\\\
Cheers
My Compilers (M$VC6,gcc,cxx) don't seem to think so. They all compile but have trouble finding the method signature during link time.
class LibLoader
{
public:
static LibLoader* Instance ();
bool doesLibExist (const char* libName) const;
TLIB_ID loadLib (const char* libName);
bool unLoadLib (TLIB_ID libID);
template <typename T>
T loadSymbol (const char* symbolName, TLIB_ID libID,T a) const;
}
As you can probably tell the class is a dynamic library loader which is also a singleton.
The original problem stemed from loading the symbol to a correct type (void*) -> (definable function pointer). I achieved this easily with a simple template function however my efforts to clean it all up and put it in the class are proving problematic.
This is what i would ideally like to have....
//load library
TLIB_ID libID = LibLoader->loadLib("msvcrt
// define symbol type
typedef int (*myFunctionType)(const char*);
// create a variable for use
myFunctionType a = 0;
// load the symbol with the help of a template method nested inside a non-templated class
a = LibLoader->loadSymbol("ato
I32 x = a("1234");
This is what works for now with the help of the templated function FuncEntry(.....) as defined below
template <class T>
T FuncEntry(T a,void *vEntry)
{
long lEntry = ACE_reinterpret_cast (long, vEntry);
return ACE_reinterpret_cast (T, lEntry);
}
void *entry;
typedef int (*myFunctionType)(const char*);
myFunctionType a = 0; // just to initialise b 4 use
TLIB_ID libID = LibLoader->loadLib("msvcrt
entry = LibLoader->loadSymbol("ato
a = FuncEntry(a,entry);
int x = a("1234");
/////////////////////////\
Cheers
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
discard the last template with two types, it won't work.
ASKER
The problem is that the symbol signature is going to change every time. I only used atoi as an example and seeing that atoi's sig is
int (__cdecl*)(const char*)
that is why you cannot embed the types into the method...
The real problem here is using templates inside a class without defining the class to be a template class. This also must be done in a platform independent manner.
I.E. This means abiding by ANSI c++ guidelines.
The first comment Kimpan is cool if it works on VC++ however it doesn't seem to work on my vc++ (w/sp3) as i outlined in my previos post nor does it work with gcc or cxx. I assume i'm breaking ANSI rules however I'm just curious to see if there is a way to get around this.
I just realised somthing. My implementaion was outside of the header defenition. I've just tested my old code using the code inside the header and all works fine on vc++... but now I'm not happy about code being in a def file... :<
There's never a totally happy moment in coding.
int (__cdecl*)(const char*)
that is why you cannot embed the types into the method...
The real problem here is using templates inside a class without defining the class to be a template class. This also must be done in a platform independent manner.
I.E. This means abiding by ANSI c++ guidelines.
The first comment Kimpan is cool if it works on VC++ however it doesn't seem to work on my vc++ (w/sp3) as i outlined in my previos post nor does it work with gcc or cxx. I assume i'm breaking ANSI rules however I'm just curious to see if there is a way to get around this.
I just realised somthing. My implementaion was outside of the header defenition. I've just tested my old code using the code inside the header and all works fine on vc++... but now I'm not happy about code being in a def file... :<
There's never a totally happy moment in coding.
ASKER
Here's the error as it appears if i put the implementation in the cpp file... if it goes in the header i get no problems....
any ideas anyone....???
Linking...
TestBase.obj : error LNK2001: unresolved external symbol "public: int (__cdecl*__thiscall TeccoLibLoader::loadSymbol (char const *,int,int (__cdecl*)(char const *)))(char const *)" (?loadSymbol@TeccoLibLoade r@@QAEP6AH PBD@Z0HP6A H0@Z@Z)
..\..\bin\test1.exe : fatal error LNK1120: 1 unresolved externals
Here's the header def
class LibLoader
{
template <typename T>
T loadSymbol (const char* symbolName, TLIB_ID libID,T a);
}
and the impl
template <typename T>
T LibLoader::loadSymbol(cons t char* symbolName, TLIB_ID libID,T a)
{
void* vEntry;
long lEntry;
vEntry = loadSymbol(symbolName,libI D);
lEntry = ACE_reinterpret_cast (long, vEntry);
return ACE_reinterpret_cast (T, lEntry);
}
Why oh why???
any ideas anyone....???
Linking...
TestBase.obj : error LNK2001: unresolved external symbol "public: int (__cdecl*__thiscall TeccoLibLoader::loadSymbol
..\..\bin\test1.exe : fatal error LNK1120: 1 unresolved externals
Here's the header def
class LibLoader
{
template <typename T>
T loadSymbol (const char* symbolName, TLIB_ID libID,T a);
}
and the impl
template <typename T>
T LibLoader::loadSymbol(cons
{
void* vEntry;
long lEntry;
vEntry = loadSymbol(symbolName,libI
lEntry = ACE_reinterpret_cast (long, vEntry);
return ACE_reinterpret_cast (T, lEntry);
}
Why oh why???
eeh, templates are declarations and they must be in in the headerfile. Am I right?
ASKER
you may just be.... my C++ primer 3rd edition says nothing of it but it does say templates are defenitions... does this mean i can make a .tpl file and inlcude it in the header....
I've seen people creating a template file before for template
implementations... is this the reason...???
I've seen people creating a template file before for template
implementations... is this the reason...???
ASKER
Well here's my problem for anyone interested...
templates are not functions ... duh!.. they can't be compiled seperately. Templates have to be used in conjunction with requests for particular instatiation of templates...
They must be included with the header file.
Only newer compilers implementing the export keyword can do have template methods in the implemenation file. How they do this my book doesn't say so anyone else who wishes to elaborate further on this issue please stand up.
templates are not functions ... duh!.. they can't be compiled seperately. Templates have to be used in conjunction with requests for particular instatiation of templates...
They must be included with the header file.
Only newer compilers implementing the export keyword can do have template methods in the implemenation file. How they do this my book doesn't say so anyone else who wishes to elaborate further on this issue please stand up.
My instructor in a course I had recently told me that some compilers support having templates in ~headerfiles. You use export keyword. As the link tells you Comeau Compiler allows that.
ASKER
cheers Kimpan...
Thanks for the pointers...
Thanks for the pointers...
This question didn't show any activity for more than 21 days. I will ask Community Support to close it unless you finalize it yourself within 7 days.
You can always request to keep this question open. But remember, experts can only help if you provide feedback to their comments.
Unless there is objection or further activity, I will suggest to accept
"Kimpan"
comment(s) as an answer.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
========
Werner
You can always request to keep this question open. But remember, experts can only help if you provide feedback to their comments.
Unless there is objection or further activity, I will suggest to accept
"Kimpan"
comment(s) as an answer.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
========
Werner
Force accepted
** Mindphaser - Community Support Moderator **
** Mindphaser - Community Support Moderator **
template <typename T>
T loadSymbol(const char* symbolName, TLIB_ID libID,T a)const;
The argument a is of type T and you are returning same type.
When I read further down, you have declared a function pointer with const char* argument and int as return value.
So to make your template to work, it should be:
template <typename T>
int loadSymbol(const char* symbolName, TLIB_ID libID,T a)const;
or why not declare template like this:
template<typename T, typename U>
U loadSymbol(const char*, symbolName, TLIB_ID libID, T a) const;