#39 wcsnlen not an export of msvcrt.dll on xp sp3

Peter Hurley

Using tdm64-gcc-4.5.1 on xp sp3, libmsvcrt.a has a relocation record to msvcrt.dll for wcsnlen but wcsnlen is not an export of msvcrt.dll on xp (sp2 or sp3).

dumpbin shows the following wcs-related exports for xp sp3:
PS C:\temp> dumpbin /exports c:\windows\system32\msvcrt.dll | grep wcs
164 A3 00025390 __wcserror = ___wcserror
552 227 00036784 _wcsdup = __wcsdup
553 228 0002647B _wcserror = __wcserror
554 229 000367BD _wcsicmp = __wcsicmp
555 22A 00036871 _wcsicoll = __wcsicoll
556 22B 00036917 _wcslwr = __wcslwr
557 22C 00036A3B _wcsncoll = __wcsncoll
558 22D 00036ABB _wcsnicmp = __wcsnicmp
559 22E 00036B82 _wcsnicoll = __wcsnicoll
560 22F 00036C46 _wcsnset = __wcsnset
561 230 00036C76 _wcsrev = __wcsrev
562 231 00036CB2 _wcsset = __wcsset
563 232 0000CD5D _wcstoi64 = __wcstoi64
564 233 0000CD7C _wcstoui64 = __wcstoui64
565 234 00036CD4 _wcsupr = __wcsupr
731 2DA 0000D380 mbstowcs = _mbstowcs
807 326 00037E61 wcscat = _wcscat
808 327 00037EB8 wcschr = _wcschr
809 328 00037EE3 wcscmp = _wcscmp
810 329 00037F1F wcscoll = _wcscoll
811 32A 00037E94 wcscpy = _wcscpy
812 32B 00037F81 wcscspn = _wcscspn
813 32C 0003AF0F wcsftime = _wcsftime
814 32D 00037FCC wcslen = _wcslen
815 32E 00037FEB wcsncat = _wcsncat
816 32F 0003802F wcsncmp = _wcsncmp
817 330 0003806B wcsncpy = _wcsncpy
818 331 000380B0 wcspbrk = _wcspbrk
819 332 000380F9 wcsrchr = _wcsrchr
820 333 00038132 wcsspn = _wcsspn
821 334 00038180 wcsstr = _wcsstr
822 335 0000D8C5 wcstod = _wcstod
823 336 000381E6 wcstok = _wcstok
824 337 0000DC2B wcstol = _wcstol
825 338 0000DE16 wcstombs = _wcstombs
826 339 0000DC4A wcstoul = _wcstoul
827 33A 00038292 wcsxfrm = _wcsxfrm

Using wcsnlen in your application yields the following error message box:
[Program Name] - Entry Point Not Found
The procedure entry point wcsnlen could not be located in the dynamic link library msvcrt.dll


  • Jonathan Yong
    Jonathan Yong


    It is not a bug, Windows 7 has it.

    Its probably not a good idea for the header to provide the prototype if _WIN32_WINNT is less than 0x0601.

  • Ozkan Sezer
    Ozkan Sezer

    A wcsnlen() implementation has recently been added to libmingwex.a by Kai. So, we should either remove the wcsnlen exports from msvcr*.def or follow the same path as we did with strnlen and mark them as DATA in msvcr*.def. The wcsnlen export is also present in ntdll.def and ntoskrnl.def since they have been updated from win7 files, however I am not sure what would be the best thing to do with those particular defs.

  • NightStrike

    Wouldn't a user only want to use the libmingwex variant on older versions of Windows?

  • Kai Tietz
    Kai Tietz

    At revision 3823 I marked the wcsnlen export as DATA. By this always the libmingwex function is used, when using msvcrt.dll. But the imp-symbol is still present within import-library, so that linking with objects generated by other compilers (or older versions) still be able to link against the imported-symbol.

  • Kai Tietz
    Kai Tietz

    • status: open --> closed-fixed
  • Kai Tietz
    Kai Tietz

    jon_y. It is for sure a flaw to mix in crt-headers with defines from psdk. Issue is that older runtime-versions don't provide this function, so we either have to provide a general function-replacement for it, or we have to live by the fact that older runtimes don't provide some functions.

    It is no mingw-w64 bug. I can be accepted as feature-request, but not as bug.

  • Kai Tietz
    Kai Tietz

    • labels: 1008199 -->
  • herrmayer

    Hi Kai,
    Thanks for your answer on the other thread about strnlen.
    But I don't see the workaround ... or is it the strnlen marked as DATA in msvcrt.def ?
    Thanks for your help

  • Kai Tietz
    Kai Tietz

    Well, to mark strnlen as DATA in imports is just a part of this. Additionally we need to add to our libmingwex.a libary a local implementation of strnlen.

    To this local implementation I was referring here by "work-a-round". As it should be enough to add such a function-implementation to blender's source.

    Something like this

    size_t __cdecl
    /*ic_*/strnlen (const char *s, size_t n)
    size_t i;

    for (i = 0; i < n && *s != 0; i++)

    return i;

    We can add this to our branches and trunk. Not sure if we should? Ozkan, JonY, any special opinion about this?


    PS: We might be able to get a bit more performance in out math-functions. If you are interested in this, we can discuss this on public ML.