如何将指向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的基本窗口界面上,我不明白为什么会出现任何丢失的组件。
救命!
我要感谢那些关注这个问题的人,尤其是那些提供了一些反馈的人。我能够解决这个最初的问题,我正在找回指针。看起来我只需要发送和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#设置级别?
感谢