1

ストレート C Win32 アプリケーションの一部として使用する必要がある C# ライブラリがあります。C# .NET オブジェクトを処理できるC++ / CLIでラッパーを作成しようとしています。唯一の問題は、プロジェクト全体を C++ でコンパイルできず、C のままにしなければならないことです。

この問題を解決するために、C# オブジェクトのインスタンスを C コードに不透明に渡して、ラッパー ライブラリ呼び出しで渡して使用できるようにしたいと考えていますが、その方法がわかりません。たとえば、次のようなことをしたいと思います。

C++ / CLI ラッパー:

void * ReturnObject(char *name){
  return (void *)gcnew MyObject(gcnew String(name));
}

void UseObject (void *object){
  MyObject ^handle = (MyObject ^)object;
  object -> use();
}

C++ スタティック ライブラリを使用したネイティブ C コード:

int main (char **argv){
  void *obj = ReturnObject("foobar");
  UseObject(obj);
}

したがって、C コードは の内容を気にすることはobjなく、 CLR の type についても認識しませんが、MyObjectオブジェクトの永続性を維持するためにデータを渡すだけです。これはポインターを使用して行う必要があると考えましvoidたが、C++ コンパイラーはキャストを実行したくありません。管理されたメモリと管理されていないメモリの違いによるものなのか、それとも正しく実行していないだけなのかはわかりませんが、助けていただければ幸いです。

要約すると、C++ / CLI ラッパー ライブラリで .net オブジェクトをインスタンス化し、それらのオブジェクトをストレートな C コードで保持して、まだ記述していない他の C++ / CLI ライブラリ呼び出しで再び使用できるようにしようとしています。

助言がありますか?

4

1 に答える 1

3

ハンドルを void* に格納することはできません。これは、ガベージ コレクターがオブジェクトを移動できるため、ポインターが役に立たないというよりも悪化する可能性があるためです (ポインターは他のランダム オブジェクトを指すようになります)。

gcrootC++/CLI が提供するテンプレートを使用する必要があります。gcroot<MyObject>*その後、aに格納しvoid*て C コードに渡すことができます。gcroot使い終わったら、デストラクタが実行されるように、を適切に解放することを忘れないでください。

GCHandle.NET クラス ライブラリの一部であるクラスを調べることもできます。ただしgcroot、C++/CLI コードでは推奨されます (GCHandle内部的に使用されます)。

于 2012-04-10T16:13:32.223 に答える