C#和C++之间的可变指针接口

3

我目前遇到了转换的问题。我有一个C++包装器,可以公开一个函数...

public __gc class InternalModuleConfig : public ModuleConfig
{
Object* InternalModuleConfig::CommitChanges(IModuleConfig* config)
{
    VARIANT variant = {0};
    m_pModuleConfig = config;
    HRESULT hr = m_pModuleConfig->CommitChanges(&variant);

    if (FAILED(hr))
    {
        VariantClear(&variant);
        return Marshal::GetObjectForNativeVariant(&variant);
    }

    return NULL;
};
};

我正在尝试在C#中调用这个函数,但是失败了。我有一个带有以下命名空间的C#接口:

DirectShow.IModuleConfig

现在我正在尝试获取指向我的现有接口的指针,以将其用作C#中CommitChanges变量的变量,但是我总是遇到转换错误。

这是我尝试的基础内容...

InternalModuleConfig config;
config.CommitChanges(ref (filter as IModuleConfig));

这不起作用...我有点困惑如何为参数应用IModuleConfig*类型。

有什么想法吗?

编辑: 这是InternalModuleConfig基于的接口:

public __gc interface ModuleConfig : public IDisposable
{
public:
virtual Object* CommitChanges(IModuleConfig* config) = 0;
IModuleConfig* m_pModuleConfig;
};
3个回答

2

我已经有一段时间没有使用C++/CLI了,但如果你想要一个C# ref参数,我认为你需要在C++中使用指向指针的指针。

Object* InternalModuleConfig::CommitChanges(IModuleConfig** config) 

托管堆中的每个对象都通过指针访问。为了允许在函数内更改指针(ref语义),您需要一个指向该指针的指针。

或者,如果您不打算使用ref语义,请在C#端删除该修饰符,然后应该可以传递托管对象。


2

将C++/CLI接口暴露给C#时,必须使用跟踪句柄而不是指针或引用:

virtual Object^ CommitChanges( IModuleConfig^% config) = 0;

(该参数的语法表示通过引用传递的跟踪句柄,这是C++/CLI中等效于C# ref参数的方式)

我正在使用clr/oldsyntax,但它不支持跟踪句柄... 有什么解决办法吗? - bl4kh4k
我必须将其设置为旧语法,因为第三方头文件中存在依赖关系。 - bl4kh4k

1

那样行不通;如果该方法将不同的IModuleConfig实现放入字段中,会发生什么?

相反,使用正确的变量类型:

IModuleConfig config = something;
config.CommitChanges(ref filter as IModuleConfig);

这仍然不起作用...我在C++中更新了我的问题与接口...但是我在c#中得到的错误是无法将'ref DirectShow.IModuleConfig'转换为'IModuleConfig',然而...Directshow实现是基于相同的IModuleConfig。 - bl4kh4k
@bl4kh4k:你需要使用“相同”的类型,而不是兼容的类型。C#不是鸭子类型。 - SLaks
我无法使用IModuleConfig的CommitChanges,因为在C#中,它最初接受的VARIANT变量不受支持。所以我决定编写一个包装器,最终覆盖从ModuleConfig接口获取IModuleConfig *指针的函数。也许我没有正确理解你的解决方案? - bl4kh4k
@bl4kh4k,“在C#中,最初使用的VARIANT变量不受支持”--此时使用object,它会被转换为/从VARIANT - user743382
@hvd:我也是这么想的,但我并没有创建原始的IModuleConfig...它实际上是一个MainConcept接口,用于访问MP4 Muxer的属性。我将其设置为Object,并且每个其他函数都可以通过这种方式工作,但是CommitChanges是唯一一个不能使用Object类型并且只返回无效参数HRESULT的函数。 - bl4kh4k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接