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 withexternkeyword;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
pRandomNumberas 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@8not valid c/c++ name. you can define such name in asm code but not in c/c++. but you can use/alternatenamelinker option.if linker not found
__imp__RandomNumber@8it try use___imp_RandomNumberif it exist. and__imp_RandomNumberwill be decorated to___imp_RandomNumberin_X86_possible write next macro
with this you code will be
and you got
if not use return value of
RandomNumber