#Declare extern fn and assign to GetProcAddress() result

1 messages · Page 1 of 1 (latest)

winter summit
#

I'm following https://ziglang.org/documentation/master/#Functions and declare an extern fn, e.g. extern fn foo() u32;

But when I do foo = std.os.windows.kernel32.GetProcAddress(hMod, "foo").?;

it cannot be converted because foo is const. What would be the right way to do this?

cloud compass
#

well of course you can't assign to foo, it's a function
same case as in at least most languages

spare perch
#

if you want to dynamically look it up you just assign it to whatever variable

cloud compass
#

extern just means it's defined somewhere else and the linker should provide it for you

spare perch
#

if that's at local scope, that just means e.g. const foo = std.os.windows.kernel32.GetProcAddress(hMod, "foo").?;

cloud compass
#

you need to cast it tho right?

spare perch
#

and of course you probably ought to cast it yes

cloud compass
#

right found it, GetProcAddress returns ?*opaque{}, so you need to check for null and cast to whatever function type is appropriate

winter summit
#

OK, got it:

const proc = std.os.windows.kernel32.GetProcAddress(hMod, "foo").?;
const foo = @neat beaconast(*const fn() u32, proc);

spare perch
#

hey ptrc

#

protip: surround your code with backticks (`) in order to avoid things like that lol

#

but yeah, also, don't forget to make that a *const fn() callconv(.C) u32

#

or else you might get some weird results

cloud compass
#

and you might want to just use extern and let the linker handle it for you, unless you really want to load it at runtime

winter summit
spare perch
#

well, that's not always feasible. A lot of applications require runtime loading. E.g., opengl or vulkan driveres

cloud compass
spare perch
cloud compass
#

true

spare perch
#

but otherwise once you understand linking lingo, it becomes quite immediately apparent what it means

#

"or at runtime, when linking dynamically" means that the symbol will get its definition linked during the run of the program, meaning the compiler will make it a weak symbol, not that you are allowed to reassign it

cloud compass
#

just for completeness, a variables you are allowed to assign a function pointer to would be declared like this var fun: *const fn(argTypes) returnType = someFun

winter summit
spare perch
#

yeah fair 'nuff

#

but now y'know

rapid raven
#

Generally there's three types of linking;
Static linking
Dynamic linking
Runtime linking

Static linking does all the resolving during the compile of your software. Larger binaries but theoretically fastest.

Dynamic linking means that the image loader for the operating system looks for all the dependencies from the import and export directories in the executable file during the start of the process and links. If something is missing on windows you get one of those MessageBoxes with 'missing dll'

With runtime linking the programmer does the work himself. You'll in this case use GetProcAddress to get an address to an export from the portable executable.

I hope this clears up the confusion

foggy flare
#

Runtime liking is often called "dynamic loading", which gets easily confused with "dynamic linking"

#

and it's sometimes called dynamic linking too

rapid raven
#

Interesting, never met anyone that calls it that. I don't think using those terms for something so inherently different works if I'm honest.