8

マネージド コールバックをアンマネージド TCP レシーバーに渡す必要があります。アプリケーションの存続期間中に存在する必要があるスレッドであるため、ガベージ コレクションが発生しないようにする必要があります。関数ポインターをピン留めする必要はなく、GCHandle.Alloc がガベージ コレクションを防止するということをどこでも読んだことがあります。

しかし、これは与えられたものですか?このコードをホストしている AppPool がアクセス違反でクラッシュすることを確認しました。関数ポインターがガベージ コレクトされたためにこのエラーが発生するという事実を疑わないのはなぜですか?

この投稿は、この事実を裏付けています。

更新: これにより、クラッシュが大幅に減少したようです。このアプローチに問題はありますか?

typedef void (__cdecl *ProcMessageFunc)(void* param, void* paramBuf, ULONG bufSize);
FuncDelegate^ fp = gcnew MessageFuncDelegate(this, &Handler); 
pin_ptr<MessageFuncDelegate^> pinnedFunctionPointer = &fp; 
ret = Receiver ((ProcMessageFunc)pinnedFunctionPointer);
4

1 に答える 1

9

私はあなたが提案することを正確に行います-デリゲートのGCHandle.Allocですが、ピン留めはありません-多くの異なるプラットフォームおよび.NETバージョン2.0-4での広範な使用で問題はありませんでした。次のようなもの:

 DelegateHandle = GCHandle.Alloc(xlDelegate);
 FunctionPointer = Marshal.GetFunctionPointerForDelegate(xlDelegate);

その後、ネイティブ コードにFunctionPointer渡され、DelegateHandle後でクリーンアップするために保持されます。

これが最良のリファレンスのようです: http://msdn.microsoft.com/en-us/library/367eeye0(v=vs.80).aspx

あなたが指摘している投稿には、この参照と矛盾するものは何もありません。デリゲートをガベージ コレクションから保護する必要があります。ピン留めが必要ないというだけです。

于 2012-07-09T19:28:25.613 に答える