大家好日子。
我需要你用g ++技能来理解我发生的事情!
尝试链接时,g ++告诉我:
undefined reference to `bool Script::Call<bool>(asIScriptFunction*, std::string, ...)'
该功能在该文件中明确定义:
namespace Script
{
template<typename RET>
RET Call(asIScriptFunction* function, string fmt, ...)
{
asIScriptContext* context = Script::Engine::Get()->CreateContext();
va_list ap;
context->Prepare(function);
va_start(ap, fmt);
for (unsigned short i = 0 ; fmt[i] ; ++i)
{
if (i == 'O')
context->SetArgObject(i, va_arg(ap, void*));
else if (i == 'b')
context->SetArgByte(i, va_arg(ap, int));
else if (i == 'i')
context->SetArgDWord(i, va_arg(ap, int));
else if (i == 'f')
context->SetArgFloat(i, va_arg(ap, double));
}
va_end(ap);
context->Execute();
RET to_ret = ScriptCallGetReturn<RET>(context);
context->Release();
return (to_ret);
}
}
namespace Script
{
template<> bool Call<bool> (asIScriptFunction*, string fml, ...);
template<> int Call<int> (asIScriptFunction*, string fml, ...);
template<> float Call<float>(asIScriptFunction*, string fml, ...);
template<> void* Call<void*>(asIScriptFunction*, string fml, ...);
template<>
void Call<void>(asIScriptFunction* function, string fmt, ...)
{
asIScriptContext* context = Script::Engine::Get()->CreateContext();
va_list ap;
context->Prepare(function);
va_start(ap, fmt);
for (unsigned short i = 0 ; fmt[i] ; ++i)
{
switch (fmt[i])
{
case '0':
context->SetArgObject(i, va_arg(ap, void*));
break ;
case 'b':
context->SetArgByte(i, va_arg(ap, int));
break ;
case 'i':
context->SetArgDWord(i, va_arg(ap, int));
break ;
case 'f':
context->SetArgFloat(i, va_arg(ap, double));
break ;
}
}
va_end(ap);
context->Execute();
context->Release();
}
}
实际上,应该编译这些模板(它们实际上是在使用它们的同一文件中)。 这可能是什么原因发生的?可能是因为我使用了stdarg?
答案 0 :(得分:4)
声明了该函数,但未在那里实现。链接器正在寻找实现。请注意,您提供的代码中只实现了Call<void>
,但Call<bool>
不是。
要使代码正确链接,您只需删除声明:
template<> bool Call<bool> (asIScriptFunction*, string fml, ...);
template<> int Call<int> (asIScriptFunction*, string fml, ...);
template<> float Call<float>(asIScriptFunction*, string fml, ...);
template<> void* Call<void*>(asIScriptFunction*, string fml, ...);
答案 1 :(得分:2)
模板&LT;&GT; bool Call(asIScriptFunction *,string fml,...);
这不符合你的想法。这是使用template <typename RET> Call
&lt; - RET
声明bool
的完整模板专精。你还没有定义它,那个旧的定义就出了门。功能模板专业化是一种奇怪的野兽,可能是最好的避免。
我认为,您要做的是告诉编译器您将使用Call
的实例化。你不需要这样做。只需使用它。
bool variable_name = Call<bool> (some_script, other_args);