+++ This bug was initially created as a clone of Bug #573087 +++ Go WINAPI. It's stdcall in ABI, but the symbols are aliased to non-decorated (cdecl-style) names and exported. So doing let registerclass = libuser32.declare("RegisterClassA", ctypes.stdcall_abi, ...); will try to look up "_RegisterClassA@..." and fail. [For now, this can be worked around thusly: let registerclass_symbol = libuser32.declare("RegisterClassA", ctypes.default_abi, ctypes.void_t); let registerclass = ctypes.cast(registerclass_symbol, ctypes.FunctionType(ctypes.stdcall_abi, ctypes.int, [ctypes.int]).ptr); ] I'm not sure what we should do here. We have two choices. 1) Introduce ctypes.win_abi (or ctypes.winapi_stdcall_abi?), which is stdcall without decoration. 2) For stdcall symbols, first look up the decorated name, and fall back to the undecorated one. 1) adds an extra bit of complexity for people to be aware of. 2) is less predictable. It could get us into trouble where a cdecl function of the same name exists -- pretty unlikely, but possible. (Or a non-WINAPI stdcall symbol, where you wanted the WINAPI one -- but let's assume that never happens in WINAPI dll's.) I'd note that 1) isn't foolproof either; if 2) would fail for either of these reasons, you'd have to be sharp for 1) not to fail too. The difference with 2) is that, to fix it, you have to resort to the hack above. I don't know how prevalent the symbol export aliasing is. If it *only* occurs in WINAPI, then we can probably assume zero collisions and do 2). If it's used in the wild... Thoughts?
ctypes.winapi_abi sounds right to me.
Another option would be to do: let foo = lib.declare(ctypes.winapi("Bar"), ctypes.stdcall_abi, ...) where the 'ctypes.winapi' object is just a wrapper that tells declare() how to mangle. Probably a bit subtle, though; winapi_abi is simpler, if not quite as elegant.
Created attachment 464113 [details] [diff] [review] patch Adds ctypes.winapi_abi.
Did this get merged over with the TM merge that happened on Friday?