0

マネージド クラスのラッパーを作成して、ネイティブ コードから呼び出すことができるようにしようとしています。

マネージ関数は次のとおりです。

void MyManagedFunction(MyStruct iStruct)
{
  // Code according to what are the types of the 2 MyStruct members
}

struct MyStruct
{
  public MyStruct(Object iValue1, Object iValue2) : this()
  {
    Value1 = iValue1; // Often contains DateTime::Now
    Value2 = iValue2;
  }

  public Object Value1;
  public Object Value2;
}

私の場合、Value1 はほぼ常に System::DateTime::Now になり、Value2 はほぼ常に共通のデータ型 (int、double、float、string、bool) になります。ラッパーに 2 つのテンプレート関数を作成することを考えました。

ラッパーの .h には、次のものがあります。

#ifdef MYWRAPPER_EXPORTS
#  define MYWRAPPER  __declspec(dllexport)
#else
#  define MYWRAPPER  __declspec(dllimport)
#endif  

class MYWRAPPER MyWrapper
{

public:
  MyWrapper();
  ~MyWrapper();

  template <class T> void MyNativeFunction(T iParam1)
  {
    MyStruct^ wStruct = gcnew MyStruct(System::DateTime::Now, iParam1);
    //The class containing the managed function is a singleton
    MyManagedClass::Instance->MyManagedFunction(wStruct); 
  }

  template <class T, class W> void MyNativeFunction(T iParam1, W iParam2)
  {
    MyStruct^ wStruct = gcnew MyStruct(iParam1, iParam2);
    //The class containing the managed function is a singleton
    MyManagedClass::Instance->MyManagedFunction(wStruct);
  }
};

このラッパーは問題なくコンパイルされました。この問題は、純粋なネイティブ コードに .h を含めたときに明らかに発生しました。テンプレート化された関数の内容を隠すことはできないため、ネイティブ コードのコンパイルを妨げるネイティブ側に表示されるものを管理しました。

これを達成するための回避策があるかどうか疑問に思っていました。関数のパラメーターとしてプリミティブ型のみを使用することに制限されていてもかまいません。最善の方法は、テンプレート化された関数のコンテンツをネイティブ コードで単純に非表示にして、シグネチャのみを認識できるようにすることです。

これまでに試した/検討したことは次のとおりです。

  • パラメータを void* に変換し、管理対象の関数を呼び出す関数を呼び出します。そうすることで、void* をオブジェクトにキャストできなくなります。型が失われ、typeid を使用して 'T' または 'W' 型を取得しても、コンパイラによって異なるため役に立ちません。
  • 使用したいすべてのタイプの関数をオーバーロードします。これは、より良い解決策が見つからない場合に使用する可能性が最も高いものです。問題は、それが多くのオーバーロードを意味することです(特に、組み合わせの数を考慮した2パラメーター関数の場合)
4

1 に答える 1

1

テンプレートが使用するすべてのタイプがわかっている場合は、それらの変数を使用してテンプレートを強制的にインスタンス化し、テンプレート関数のコードをヘッダーではなくソースファイルに配置できます。

C++テンプレート関数定義の.CPPファイルへの保存で提供されている例を見ることができます。

彼が言うように、あなたは以下のように行うことができます(コピー&ペーストアラート):

.hファイル

class foo
{
public:
    template <typename T>
    void do(const T& t);
};

.cppファイル

template <typename T>
void foo::do(const T& t)
{
    // Do something with t
}

template void foo::do<int>(const int&);
template void foo::do<std::string>(const std::string&);
于 2012-12-14T02:03:17.887 に答える