如何将指向COM接口的指针传递给C#中的方法

本文关键字:方法 指针 COM 接口 | 更新日期: 2023-09-27 18:26:19

我正在为教室类型的环境编写一个小型实用程序。其目的是确保所有系统每天都以正确的音频捕获基线开始。捕获的音频与外语技能有关,需要非常一致。该应用程序将用于多个不同的类别,每个类别最多有30台机器。

我在Win7系统上使用C#访问核心音频API。我需要的部分内容是在包装器dll CoreAudioAPI.dll中找到的,它处理MMDevice和EndpointVolume API。有了它,我可以设置麦克风和扬声器的音量。

我需要设置的最后一个设置是Microphone Boost,在大多数系统的UI上,它显示为DB+值为0到40的滑块。为了达到这个设置,我需要添加到现有的包装器dll中以访问DeviceTopology API。除了一个问题,我已经能够用这个解决所有问题。我可以访问设置,但为了能够看到它的值并进行设置,我必须能够将指针传递到其中一个接口。

我在一个单独的类中调用一个例程,该例程负责连接到设备并找到我需要的设置。

呼叫线路:

mbs.DecibelLevel(ref IAudioVolumeLevel pInterface);

传递的值需要是指向接口的指针,而不是指向接口本身的引用。

这项工作是在各种拓扑结构中循环完成的,直到找到麦克风提升。下面的行返回IAudioVolumeLevel接口的指针值,该指针值应该从调用行传入。

public void DecibelLevel(ref IntPtr audioVolumeLevelPtr)
{
    ...
    _PartNext.Activate(CLSCTX.ALL, ref IID_IAudioVolumeLevel, out audioVolumeLevelPtr);
    ...
}

如何将指向C#中IAudioVolumeLevel的指针从调用例程传递到工作例程,以便获取并设置它。

提前感谢您的帮助。

编辑:我尝试了这个例子,我发现得到了一个指针对象,但第二行失败了,出现了8004:

// Use the CLSID to instantiate the COM object using interop.
Type type = Type.GetTypeFromCLSID(IID_IAudioVolumeLevel);
Object comObj = Activator.CreateInstance(type);
// Return a pointer to the objects IUnknown interface.
IntPtr pIUnk = Marshal.GetIUnknownForObject(comObj);
IntPtr pInterface;
Int32 result = Marshal.QueryInterface(pIUnk, ref IID_IAudioVolumeLevel, out pInterface);

这本应为我提供另一个调用的指针,但在Activator.CreateInstance调用中出现错误,接口上有80040154。由于这是在音频API的基本窗口界面上,我不明白为什么会出现任何丢失的组件。

救命!

如何将指向COM接口的指针传递给C#中的方法

我要感谢那些关注这个问题的人,尤其是那些提供了一些反馈的人。我能够解决这个最初的问题,我正在找回指针。看起来我只需要发送和IntPtr作为ref参数并使用它。

这给我留下了另一个问题,我还没有找到明确的答案。现在我有了指针值,我该如何使用它来到达实际的接口?我已经定义了能够访问COM:的C#接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CoreAudioApi.Interfaces
{
    [Guid("7FB7B48F-531D-44A2-BCB3-5AD5A134B3DC"),
     InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IAudioVolumeLevel : IPerChannelDbLevel { }
}

这与COM接口相连,也是我其他接口的设置方式。我使用的C++示例发送了一个从接口定义的指针:

IAudioVolumeLevel* pIaudioVolumeLevel;
getMicrophoneBoostVolumeLevel(defaultDevice, &pIaudioVolumeLevel);

返回时,可以检查并设置该特定部件的音量设置:

pIaudioVolumeLevel->GetLevelRange(0, &fMinDb, &fMaxDb, &fStepDb);
pIaudioVolumeLevel->GetLevel(0, &pfCurrentDb);
pIaudioVolumeLevel->SetLevel(0, pfCurrentDb, NULL);

假设我在返回的指针中得到了正确的值,那么我现在如何通过C#设置级别?

感谢