-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider adding strongly-typed Vtbl property to COM interface structs (if trimmable) #289
Comments
Hmm, looks like my attempt to use generics here is not supported by the runtime, I get Having the strongly-typed |
Alright I did find a use for this, in my wrappers for There are many methods on these interfaces that are public string Author
{
get
{
if (this.author == null)
{
this.author = GetString(
this.pWICComponentInfo,
(delegate* unmanaged<void*, uint, ushort*, uint*, int>)
((IWICComponentInfo.Vtbl<IWICComponentInfo>*)this.pWICComponentInfo->lpVtbl)->GetAuthor);
// ^^^ that could be simplified to `this.pWICComponentInfo->Vtbl->GetAuthor`
}
return this.author;
}
}
// I couldn't spec this as `GetString<T>(T* pObject, ...) where T : unmanaged, IWICComponentInfo.Interface`,
// I just get BadImageFormatException
protected static string GetString(void* pObject, delegate* unmanaged<void*, uint, ushort*, uint*, int> getStringFn)
{
uint cch;
HRESULT hr = getStringFn(
pObject,
0,
null,
&cch);
hr.ThrowOnError();
if (cch == 0)
{
return string.Empty;
}
else
{
return string.Create(
(int)cch - 1,
((Ptr)pObject, (Ptr)getStringFn),
static delegate (Span<char> dst, (Ptr pObject, Ptr getStringFn) e)
{
fixed (char* pDst = dst)
{
uint cch2;
HRESULT hr = ((delegate* unmanaged<void*, uint, ushort*, uint*, int>)(void*)e.getStringFn)(
e.pObject.Get(),
(uint)(dst.Length + 1),
(ushort*)pDst,
&cch2);
hr.ThrowOnError();
if (cch2 != (uint)(dst.Length + 1))
{
throw new InternalErrorException();
}
}
});
}
} |
This is non-trivial due to there already being a member named There would need to be a different non-conflicting name available for use here. It ultimately would just be a short circuit for the user manually doing: var lpVtbl = (IUnknown.Vtbl<IUnknown>*)pUnknown.lpVtbl;
lpVtbl->QueryInterface = &QueryInterface |
We can close this, I found a reasonable solution a long time ago for this particular issue |
In implementing my wrapper for
IDWriteTextLayout
, there are 12 methods that are easily made generic, which relies on passing in a function pointer from the vtbl. These are 6 getters and 6 setters for simple unmanaged value types.Here's an example of how I'm currently implementing it. A strongly-typed
Vtbl
property onIDWriteTextLayout
would remove the need for the casting in myGet____()
andSet____()
methods. As long as the property is trimmable, theVtbl<TSelf>
struct should still be trimmable ... right?Implementation in TerraFX could be:
The text was updated successfully, but these errors were encountered: