C
C#9mo ago
Vlad

Initialize COM object in .Net 8 when using the new GeneratedComInterface and NativeAOT

Hey everyone, I'm trying to NativeAOT my app that uses COM for interaction with WasAPI. I've converted all my code to use the new .Net 8 GeneratedComInterface code generation feature, but I've reached a wall. I need to initialize a COM object of a particular type ("BCDE0395-E52F-467C-8E3D-C4579291692E") which inherits the interface ("A95664D2-9614-4F35-A746-DE8DB63617E6"). Previous I did this by just specifying the class, doing new() and casting it to the interface - which worked despite the class not inheritting the interface on the C# side. Now with GeneratedComInterface and GeneratedComClass it requires me to pair them together, but I don't have the implementation - I just want to consume the object. What is the right way to declare the class initialize the object?
2 Replies
reflectronic
reflectronic9mo ago
you would need to P/Invoke into CoCreateInstance, as you would to create the object in C++ https://learn.microsoft.com/en-us/windows/win32/coreaudio/mmdevice-api
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pEnumerator);
so, something like this in C#:
[LibraryImport("ole32")]
private static partial int CoCreateInstance(
in Guid rclsid,
nint pUnkOuter,
int dwClsContext,
in Guid riid,
[MarshalAs(UnmanagedType.Interface)]
out object ppv);

// ...

var mmDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E");

const int CLSCTX_INPROC_SERVER = 0x1;
int hr = CoCreateInstance(
mmDeviceEnumerator,
0,
CLSCTX_INPROC_SERVER,
typeof(IMMDeviceEnumerator).GUID,
out object objectDeviceEnumerator);

Marshal.ThrowExceptionForHR(hr);

var deviceEnumerator = (IMMDeviceEnumerator)objectDeviceEnumerator;
[LibraryImport("ole32")]
private static partial int CoCreateInstance(
in Guid rclsid,
nint pUnkOuter,
int dwClsContext,
in Guid riid,
[MarshalAs(UnmanagedType.Interface)]
out object ppv);

// ...

var mmDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E");

const int CLSCTX_INPROC_SERVER = 0x1;
int hr = CoCreateInstance(
mmDeviceEnumerator,
0,
CLSCTX_INPROC_SERVER,
typeof(IMMDeviceEnumerator).GUID,
out object objectDeviceEnumerator);

Marshal.ThrowExceptionForHR(hr);

var deviceEnumerator = (IMMDeviceEnumerator)objectDeviceEnumerator;
.
Vlad
VladOP9mo ago
damn yeah that works I thought I had tried it but I guess something was subtly different from your snippet
Want results from more Discord servers?
Add your server