サードパーティ プログラムで使用されている C++ dll (具体的には directshow フィルター) があります。共有メモリを介してC#プログラムで制御しています(C#側ではMemoryMappedFile、C ++ではCreateFileMapping)。
明確にするために:1つのプログラムはありません。一度に実行される 2 つの異なるプログラムであり、アンマネージ コード (C++) プログラムでマネージ コード プログラム (C#) のメソッドを呼び出す必要があります。
メモリ共有は正常に機能します。サードパーティのプログラムがdllを使用するため、C#プログラムを使用して値を変更および確認できます。
問題は、C# プログラムの一部の側面を C++ dll の値に効果的にデータバインドしたいことです。つまり、サード パーティのプログラムで使用されている dll の値が変更されるたびに、C# プログラムで自動的に更新する必要があります。
これで、C# プログラムの別のスレッドで値を毎秒ポーリングすることができます。しかし、私が望むのは、DLL が C# で PropertyChangedEventHandler を呼び出すようにすることです。または、少なくともそれを呼び出すメソッドを呼び出します。
私の最初のアプローチは、共有メモリを介して IntPtr を介して C# メソッドのデリゲートを渡すことでした。
したがって、C++ は共有メモリを見て、そのような構造体を見ます
struct MyStruct
{
//...some ints, etc
int (*ptr2Func)(int); //not sure if I need to change this to a void pointer, but then how do I cast it to a function pointer in my C++?
//...etc
}
私の C# コードは共有メモリを見て、
struct MyStruct
{
//...the same ints as in the C++
public IntPtr ptr2Func;
//etc..
}
前述したように、共有メモリ構造体の他のすべての値は正常に機能し、手動で値を確認または変更できます。
C++ dll のメイン プロセスが初期化されると、ptr2Func が NULL に設定されます。次に、実行を試みる前に NULL でないことを確認します。
次に、C# はそれをローカル メソッドに設定します。
unsafe public delegate int mydelegate(int input);
public myDelegate tempDele;
public int funcToBeCalled(int input)
{
return (2);
}
// this code is inside a button click method right after it connects the C# program to the shared memory:
tempDele = this.funcToBeCalled;
sharedInstanceOfMyStruct->pt2Func = Marshal.GetFunctionPointerForDelegate(tempDele);
構造体の関数ポインタが NULL から変更され、DLL のコードがそれを呼び出そうとするまでは、サードパーティ プログラムは問題ありません。