Let's say I import a DLL function like so:
typedef int(__stdcall *pRandomNumber)(size_t cb, unsigned char *pb);
HINSTANCE hDLL = LoadLibraryW(L"foo.dll");
pRandomNumber RandomNumber = (pRandomNumber)GetProcAddress(hDLL, "RandomNumber");
Now, this function RandomNumber
in the code of the DLL is annotated with the SAL annotation _Check_return_
. I also want to have this annotation enforced in code that calls it. How do I get that done?
If I put the annotation on the typedef
:
_Check_return_
typedef int(__stdcall *pRandomNumber)(size_t cb, unsigned char *pb);
Analysis fails to report a warning later when I initialize a pRandomNumber
and call it without checking the return value.
If I put the annotation on an instance:
typedef int(__stdcall *pRandomNumber)(size_t cb, unsigned char *pb);
_Check_return_
pRandomNumber RandomNumber;
Analysis still fails to report when I call it without checking the return value.
Is there any way I can have that enforced? One way is writing a stub inline function with the annotation on it, but that feels ugly to me.
instead of declare variable
you can declare function with
__declspec(dllimport)
attribute and use[[nodiscard]]
and/or_Must_inspect_result_
on this declarationinternally, when you declare api with
__declspec(dllimport)
attribute, compiler declare variable withextern
keyword;in place <function_name>
__FUNCDNAME__
used - the decorated name of the functionso possible say and
of course, because extern, this is only declaration. and if you not add definition - you got
if you try call
RandomNumber
. so you need add definition. for_AMD64_
this is very simply, becauseextern "C"
symbols not decorated.so simply write:
instead
you need in both case declare pointer size variable, which will be hold function pointer - different only in name - you select
pRandomNumber
as name (and can select any name) - in my case - you must select__imp_RandomNumber
(__imp_<function_name>
) - add__imp_
prefix to decorated function name.but in case
_X86_
exist problem - for__stdcall
- the @ symbol will be in decorated function name. you need writebecause decorated name will be
_RandomNumber@8
. but__imp__RandomNumber@8
not valid c/c++ name. you can define such name in asm code but not in c/c++. but you can use/alternatename
linker option.if linker not found
__imp__RandomNumber@8
it try use___imp_RandomNumber
if it exist. and__imp_RandomNumber
will be decorated to___imp_RandomNumber
in_X86_
possible write next macro
with this you code will be
and you got
if not use return value of
RandomNumber