0

サードパーティ プログラムで使用されている 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 のコードがそれを呼び出そうとするまでは、サードパーティ プログラムは問題ありません。

4

1 に答える 1

3

基本的に、これができるとは思いません。2つのプロセスは、異なるアドレススペースで実行されています。共有メモリに保存するアドレスは、C#プロセスの関数を指しますが、呼び出し元のプロセスをコーディングすることは指しません。クラッシュするだけです。

WCF、名前付きパイプ、またはソケットを使用して、トリガーメッセージを他のアプリケーションに送信できます。

于 2012-05-04T17:30:52.017 に答える