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

seb*_*ebf 6 clr c++-cli

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

我遇到这条线有问题但是:

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

在哪里graphBuilder声明:

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

    IGraphBuilder*  graphBuilder;

};
Run Code Online (Sandbox Code Playgroud)

如果我正确理解了这个页面,我可以*/&像往常一样用C++/CLI库中的非托管内存表示"本机"指针; ^用于表示指向托管对象的指针.但是,此代码生成:

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

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

(这个问题类似,但答案是,使用pin_ptr,我看不到帮助我,因为它不能成为我班级的成员)

Han*_*ant 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...
    }
}
Run Code Online (Sandbox Code Playgroud)