2009-06-26 10 views
1

ここにヒストリーレッスンのビット。私は従来のC++/MFCアプリケーションで作業しており、C#(WinFormsとそれ以降のWPF)で書かれたコンポーネントをプッシュすることによってインクリメンタルな近代化を開始しようとしています。マネージドCからアンマネージコードをコールバック

私は近い将来に解決することが不可能な多くの理由で.Net/1.1とVS/2003を使用しています。

現在、概念の証明として、このようなものは動作します:

#pragma push_macro("new") 
#undef new 

WinFormA::Form1* myform; 
myform = __gc new WinFormA::Form1(); 
myform->ShowDialog(); 

#pragma pop_macro("new") 

私がいる問題はこれです - 私は管理のC#へのコールバックポインタを渡すために管理されていないC++/MFCコードが必要です私はユーザーのやりとりをキャプチャして、アプリケーションで処理させることができるように、WinFormのコードです。

this MSDN articleなどの記事を見ましたが、VS/2003では動作しません(コンパイラはデリゲート構文が嫌いです)。

その他のオプションはありますか?フラットAPIではなく、特定のアプリケーションインスタンスと対話する必要があるため、DLLImportを使用することはできません。

ありがとうございます!

答えて

0

私はすでに.NET 1. *、しかし、忘れてしまった:

が必要なインタフェースを定義して、COMオブジェクトとして、あなたの.NETコンポーネントを登録します。 .NETユーティリティは、通常、合理的に優れたマーシャリングコードを提供します。

可能であれば、Managed C++を一切使用せずに、C++アプリケーションからCOMオブジェクトとしてアクセスできます。 (コールバックの関数の代わりにインタフェースポインタを使用する)。

COMがオプションでない場合は、.NET Reflectorを使用して、自動生成されたinteropアセンブリ内で何が起こっているかを確認します。これにより、同じことを手動で行う方法についての洞察が得られる場合があります。

0

私は自分でそれを試したことはありませんが、確かに.net1に存在するRuntimeMethodHandle構造体をチェックしましたか?

SomeDelegate Handler = new SomeDelegate(SomeMethod); 
IntPtr HandlerPtr = Handler.Method.MethodHandle.GetFunctionPointer(); 

そしてMSDNの説明.net2 元帥:: GetDelegateForFunctionPointer方法からいくつかのコピー&ペースト:バージョン1.0と.NET Framework 1.1で

、表すデリゲートを渡すことができました管理されていないコードを関数ポインタとして管理し、管理されていないコードが関数ポインタを介して管理対象メソッドを呼び出すことを許可します。また、アンマネージコードがその関数ポインタをマネージコードに戻し、ポインタが基になるマネージメソッドに正しく解決された可能性もありました。

1

他の回答がうまくいかない場合は、常にクラスをフラット化するCラッパーを作成できます。たとえば、C++クラスの場合:

class TheClass { 
    public: 
    TheClass(int Param); 
    ~TheClass(); 

    bool SomeFunction(int Param1,int Param2); 
}; 

私はラッパーを記述します:

extern "C" void *TheClass_Create(int Param) { 
    return (void*) new TheClass(Param); 
} 

extern "C" void TheClass_Destroy(void *This) { 
    delete (TheClass*) This; 
} 

extern "C" bool TheClass_SomeFunction(void *This,int Param1,int Param2) { 
    return ((TheClass*) This)->SomeFunction(Param1,Param2); 
} 

ラッパーがまっすぐCですので、あなたはP /呼び出すことができますあなたの心のコンテンツにC#で( void *このは、64ビットに移行した場合の互換性を保証するためにIntPtrになります。時には、私が本当に野心的であれば、実際にP/Invokesの周りにC#ラッパーを書いて、その事を「再分類」します。

関連する問題