线程之间以及托管代码和非托管代码之间的绑定

时间:2012-05-04 17:23:13

标签: c# c++ function-pointers shared-memory

我有一个C ++ dll(特别是一个directshow过滤器),它正在第三方程序中使用。我通过共享内存使用C#程序控制它(因此C#端的MemoryMappedFile和C ++上的CreateFileMapping)。

所以要明确:没有1个程序。这是两个不同的程序同时运行,我希望非托管代码(C ++)程序调用托管代码程序中的方法(C#)

内存共享工作正常。我可以使用C#程序来更改和检查值,因为第三方程序使用dll。

问题是我想有效地将​​我的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);

第三方程序没问题,直到struct中的函数指针从NULL变为NULL并且DLL中的代码试图调用它。

1 个答案:

答案 0 :(得分:3)

基本上,我认为你不能这样做。这两个进程在不同的地址空间中运行。存储在共享内存中的地址确实指向C#进程中的函数,但它并不指向调用进程的代码。它会崩溃。

您可以使用WCF,命名管道或套接字向其他应用程序发送触发器消息。