Skip to content

Update winlean.nim, import AddrInfo from ws2tcpip.h #24828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2025

Conversation

haoyu234
Copy link
Contributor

@haoyu234 haoyu234 commented Mar 31, 2025

ADDRINFOA.

It's unclear whether this modification will break other users' code.

@@ -437,7 +437,7 @@ type
fd_count*: cint # unsigned
fd_array*: array[0..FD_SETSIZE-1, SocketHandle]

AddrInfo* = object
AddrInfo* {.importc: "ADDRINFOA", header: "ws2tcpip.h".} = object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASCII structure in 2025, you joking?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADDRINFOA is applicable to getaddrinfo. If you want ADDRINFOW, then you should use GetAddrInfoW.

Currently, the Nim standard library uses getaddrinfo, and the GetAddrInfoW function is not imported. Users may need to import it themselves.

Nim/lib/windows/winlean.nim

Lines 571 to 576 in 10c9eba

proc getaddrinfo*(nodename, servname: cstring, hints: ptr AddrInfo,
res: var ptr AddrInfo): cint {.
stdcall, importc: "getaddrinfo", dynlib: ws2dll.}
proc freeAddrInfo*(ai: ptr AddrInfo) {.
stdcall, importc: "freeaddrinfo", dynlib: ws2dll.}

@cheatfate
Copy link
Member

What the reason to make it dependent on ws2tcpip.h.

@haoyu234
Copy link
Contributor Author

haoyu234 commented Apr 4, 2025

What the reason to make it dependent on ws2tcpip.h.

When you attempt to work with other C network libraries, the C compiler will complain about type inconsistencies.·

E:\tdns_d\@m..@ssrc@[email protected]:866:187: error: passing argument 6 of 'uv_getaddrinfo' from incompatible pointer type [-Wincompatible-pointer-types]
  866 |         nimln_(44);err_1 = uv_getaddrinfo((*loop_p0).uv_loop, ((&(*env_p6).req)), getAddrInfoCallback__OOZsrcZuvZdns_u11, nimToCStringConv(address_p1), nimToCStringConv(socketPort_1), ((&hints_1)));
      |                                                                                                                                                                                         ~~^~~~~~~~~~
      |                                                                                                                                                                                           |
      |                                                                                                                                                                                           tyObject_AddrInfo__Ia2RzOMczAgZrUvt9c4b9aZw *
E:/mingw-w64-gcc-mcf_20250120_14.2.1_x64-msvcrt/include/uv.h:995:53: note: expected 'const struct addrinfo *' but argument is of type 'tyObject_AddrInfo__Ia2RzOMczAgZrUvt9c4b9aZw *'
  995 |                              const struct addrinfo* hints);
      |                              ~~~~~~~~~~~~~~~~~~~~~~~^~~~~
E:\tdns_d\@m..@ssrc@[email protected]: In function 'freeAddrInfo__OOZsrcZuvZdns_u938':
E:\tdns_d\@m..@ssrc@[email protected]:1415:72: error: passing argument 1 of 'uv_freeaddrinfo' from incompatible pointer type [-Wincompatible-pointer-types]
 1415 |         nimlf_(66, "E:\\repos2\\uv\\src\\uv\\dns.nim");uv_freeaddrinfo(addr_p0);
      |                                                                        ^~~~~~~
      |                                                                        |
      |                                                                        tyObject_AddrInfo__Ia2RzOMczAgZrUvt9c4b9aZw *
E:/mingw-w64-gcc-mcf_20250120_14.2.1_x64-msvcrt/include/uv.h:996:49: note: expected 'struct addrinfo *' but argument is of type 'tyObject_AddrInfo__Ia2RzOMczAgZrUvt9c4b9aZw *'
  996 | UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);

On Windows, Nim doesn't map the AddrInfo type to its corresponding C type. I believe this is the root cause of the problem.

According to the Microsoft documentation, ADDRINFOA is located in ws2def.h, but it is not recommended that we directly use this header file.

Requirement Value
Minimum supported client Windows 2000 Professional [desktop apps only]
Minimum supported server Windows 2000 Server [desktop apps only]
Header ws2def.h

On the Windows SDK released for Windows Vista and later, the organization of header files has changed and this member can be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly.

I noticed that the documentation mentions:

The getaddrinfo function that uses the addrinfo structure was added to the Ws2_32.dll on Windows XP and later. The addrinfo structure is defined in the Ws2tcpip.h header file included with the Platform SDK released for Windows XP and later and the Windows SDK released for Windows Vista and later.
To execute an application that uses the getaddrinfo function and the addrinfo structure on earlier versions of Windows (Windows 2000), then you need to include the Ws2tcpip.h and Wspiapi.h files. When the Wspiapi.h include file is added, the getaddrinfo function is defined to the WspiapiGetAddrInfo inline function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo function is implemented in such a way that if the Ws2_32.dll or the Wship6.dll (the file containing getaddrinfo in the IPv6 Technology Preview for Windows 2000) does not include getaddrinfo, then a version of getaddrinfo is implemented inline based on code in the Wspiapi.h header file. This inline code will be used on older Windows platforms that do not natively support the getaddrinfo function.

According to the documentation's suggestion, I should probably include ws2tcpip.h instead of ws2def.h.

@Araq Araq merged commit b961ee6 into nim-lang:devel Apr 12, 2025
18 checks passed
Copy link
Contributor

Thanks for your hard work on this PR!
The lines below are statistics of the Nim compiler built from b961ee6

Hint: mm: orc; opt: speed; options: -d:release
179239 lines; 8.540s; 651.832MiB peakmem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants