Replies: 5 comments 9 replies
-
I'm also unhappy with the
As for "lazy importing" I've have a little experiment along these lines here in u-config: skeeto/u-config@master...no-imports It technically imports and exports nothing (check it with
Yeah, don’t build your castle in other people’s kingdoms and all. Though of course we're here in GitHub's kingdom. It comes with lots of benefits and freebees so I'm willing to make the trade-off building, in part, within this kingdom.
Done. |
Beta Was this translation helpful? Give feedback.
-
#292 is an easy freebie we could be taking. |
Beta Was this translation helpful? Give feedback.
-
|
@skeeto You still have to define function pointer prototype: https://github.com/skeeto/u-config/blob/c0f49812f1e55c4e9d73ca6f0d4bd03c03092c6d/miniwin32.h#L29 Lazy Load a DLL in Go doesn't need a function pointer prototype. |
Beta Was this translation helpful? Give feedback.
-
|
@skeeto You can convert this issue to a discussion. The button is right there on the sidebar. |
Beta Was this translation helpful? Give feedback.
-
Thanks, I just did that. I'm still learning this interface.
Hmm, I suppose if you wanted similar semantics you could do this: typedef uintptr_t Syscall(...);Go treats Win32 functions like system calls, passing everything as #define nil ((uintptr_t)0)Then maybe: typedef struct {
Syscall *ExitProcess;
Syscall *GetCommandLineW;
Syscall *GetProcAddress;
Syscall *GetStdHandle;
Syscall *LoadLibraryA;
Syscall *WriteConsoleW;
} Kernel32;
typedef struct {
Syscall *CommandLineToArgvW;
} Shell32;And then: static Kernel32 new_kernel32()
{
Syscall LoadLibraryA, GetProcAddress; // bootstrap
uintptr_t h = LoadLibraryA("kernel32");
return (Kernel32){
.ExitProcess = (Syscall *)GetProcAddress(h, "ExitProcess"),
.GetCommandLineW = (Syscall *)GetProcAddress(h, "GetCommandLineW"),
.GetProcAddress = (Syscall *)GetProcAddress(h, "GetProcAddress"),
.GetStdHandle = (Syscall *)GetProcAddress(h, "GetStdHandle"),
.LoadLibraryA = (Syscall *)GetProcAddress(h, "LoadLibraryA"),
.WriteConsoleW = (Syscall *)GetProcAddress(h, "WriteConsoleW"),
};
}
static Shell32 new_shell32(Kernel32 kernel32)
{
uintptr_t h = kernel32.LoadLibraryA("shell32");
return (Shell32){
.CommandLineToArgvW =
(Syscall *)kernel32.GetProcAddress(h, "CommandLineToArgvW"),
};
}No type safety at the call sites of course, though likely those call sites are already wrappers presenting a higher level interface. Usage example: static ptrdiff_t char16len(char16_t *s)
{
ptrdiff_t len = 0;
for (; s[len]; len++) {}
return len;
}
void mainCRTStartup()
{
Kernel32 kernel32 = new_kernel32();
Shell32 shell32 = new_shell32(kernel32);
char16_t *cmd = (char16_t *)kernel32.GetCommandLineW();
int argc = {};
char16_t **argv = (char16_t **)shell32.CommandLineToArgvW(cmd, &argc);
uintptr_t out = kernel32.GetStdHandle(-11);
for (int i = 1; i < argc; i++) {
kernel32.WriteConsoleW(out, u"hello, ", 7, nil, nil);
kernel32.WriteConsoleW(out, argv[i], char16len(argv[i]), nil, nil);
kernel32.WriteConsoleW(out, u"\n", 1, nil, nil);
}
kernel32.ExitProcess(0);
}Then: Though this technique does not work on x86 because stdcall is incompatible with these variadic calls, and you'd need to dispatch through custom assembly. Looks like the libraries you linked struggle with this, too. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Sorry for going off-topic, but I don’t trust third-party Discussions boards like #333. They tend to appear and disappear suddenly, just like the one mentioned in #305 (the maintainer left GitHub and their repositories vanished). So I’ll post it here instead. Ideally, it would be best to have a Discussions board enabled directly on this repository, as I proposed in #305.
Here are the projects I mentioned in the title of this thread:
https://github.com/JustasMasiulis/lazy_importer
https://github.com/annihilatorq/shadow_syscall
https://github.com/JustasMasiulis/inline_syscall
Of course, I don’t do any hacking like the developers of these projects. But I think the idea is cool (at least to me). I don’t want to include a large
windows.h. Instead, I can load the shared library and call functions directly without a function pointer prototype or strict type correctness. I’ve seen something similar in some Go code I came across, though I can’t remember exactly where. This is very cool.Beta Was this translation helpful? Give feedback.
All reactions