2

みなさん、良い一日を。

私に何が起こっているのかを理解するには、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を使用したことが原因でしょうか?

4

2 に答える 2

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, ...);
于 2012-09-29T23:29:22.350 に答える
2

template <> bool Call(asIScriptFunction *、string fml、...);

これは、あなたが思っていることをしていません。template <typename RET> Callこれは、 with RET<-の完全なテンプレート特殊化を宣言していboolます。あなたはそれを定義していません、そしてその古い定義は戸外にあります。関数テンプレートの特殊化は奇妙な獣であり、おそらく避けるのが最善です。

あなたがやろうとしていることは、コンパイラに、のインスタンス化を使用することを伝えることだと思いますCall。あなたはそれをする必要はありません。使用するだけです。

bool variable_name = Call<bool> (some_script, other_args);
于 2012-09-29T23:54:21.763 に答える