如何在C ++ / CLI中的引用类中使用“本机”指针?

时间:2012-05-06 16:34:01

标签: c++-cli clr

我正在尝试编写一个将使用DirectShow的小型库。这个库将由.NET应用程序使用,所以我认为最好用C ++ / CLI编写它。

我遇到了这条线路的问题:

    HRESULT hr = CoCreateInstance(  CLSID_FilterGraph,
                                    NULL,
                                    CLSCTX_INPROC_SERVER,
                                    IID_IGraphBuilder,
                                    (void**)(&graphBuilder) );  //error C2440:

声明graphBuilder的地方:

public ref class VideoPlayer
{
public:
    VideoPlayer();
    void Load(String^ filename);

    IGraphBuilder*  graphBuilder;

};

如果我正确理解this page,我可以像往常一样使用*/&来表示我的C ++ / CLI库中非托管内存的“本地”指针; ^用于表示指向托管对象的指针。但是,此代码生成:

  

错误C2440:'type cast':无法从'cli :: interior_ptr'转换为'void **'

该错误表明graphBuilder被视为'cli::interior_ptr<Type>'。那是托管内存的指针/句柄,不是吗?但它是纯粹的原生指针。我不是试图将指针传递给期望句柄的方法,反之亦然 - 我只是想将它存储在我的托管类中)如果是这样,我怎么说graphBuilder是一个“传统”指针?

This question类似但答案是,使用pin_ptr,我看不到帮助我,因为它不能成为我班级的成员)

1 个答案:

答案 0 :(得分:11)

错误消息有点神秘,但编译器试图提醒您无法将指向托管类成员的指针传递给非托管代码。这无法通过设计工作,当垃圾收集器在函数执行时启动并移动托管对象时发生灾难。使指向进程中成员的指针无效并导致本机代码将字节喷入错误地址的gc堆中。

解决方法很简单,只需声明一个局部变量并将指针传递给它。堆栈上的变量无法移动。像这样:

void init() {
    IGraphBuilder* builder;    // Local variable, okay to pass its address
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IGraphBuilder,
        (void**)(&builder) );
    if (SUCCEEDED(hr)) {
        graphBuilder = builder;
        // etc...
    }
}