15 апреля 2010 г.

WinSock и Delphi

Сегодня столкнулся со знатным подводным камнем, объяснить который я не в состоянии.

Нам пришёл запрос о том, что приложение, скомпилированное с EurekaLog, не запускается на китайской Windows XP. Просто ничего не происходит, без каких-либо внешних сообщений.

После обычной процедуры (попробуйте на пустом проекте и т.п.), мне пришлось удалённо подключиться к машине клиента и отлаживать проблему на месте. Опуская процедуру поиска причины (это не заняло много времени, хотя местами ему пришлось переводить мне текст :) ), оказалось, что в системе отсутствует wsock32.dll.

EurekaLog статически связана с wsock32.dll для отправки отчётов разработчикам. Не удивительно, что приложение, скомпилированное с EurekaLog, не запускалось. Ну, обычно в таких случаях бывает сообщение типа "компонент приложения отсутствует", но в данном случае, видимо, клиент отключил показ сообщений.

Вопрос в том, почему отсутствует библиотека. Замечу, что никаких других видимых проблем на этой машине не было. Все сетевые программы работали, как положено.

Ну, я ничего не понимаю в программировании сокетов, но насколько я понимаю, wsock32.dll - это старая версия WinSock. Может ли она отсутствовать в системе? Зная политику Microsoft по обратной совместимости - скорее всего, нет. Тем не менее, вот реальный случай.

Дальнейший поиск информации показал, что wsock32.dll упоминается очень редко (в документации не упоминается вообще). Вся документация ссылается на ws2_32.dll (сам WinSock) или mswsock.dll (расширения Microsoft для WinSock).

Как EurekaLog использует WinSock? Может это проблема только EurekaLog, её заголовочников? Хм, я посмотрел в код и увидел, что она использует стандартный модуль Delphi WinSock.pas. Открываем WinSock.pas (Delphi 2010) и видим:
const
  winsocket = 'wsock32.dll';
Гм, сюрприз.

Indy и Джедаи используют ws2_32.dll.

Решение? Сделать свой модуль WinSock, где динамически грузить ws2_32.dll, а если её нет - то wsock32.dll. Этот фикс вошёл в очередную RC версию.

Да, это не проблема EurekaLog, но её приходится исправлять нам. Клиенты не очень хорошо разбираются в том, кто виноват, зато они очень хорошо видят разницу, когда что-то работает, а когда - нет.

6 комментариев :

  1. Clever Internet Suite использует ws2_32.dll. И грузит её динамически :)

    ОтветитьУдалить
  2. > Ну в cc заслали issue?
    Если имелось ввиду Quality Central - то нет, потому что это не баг в явном виде. Навряд ли его станут исправлять.

    Проблема в системе клиента. Вероятно, что ему нужно сделать что-то вроде repair TCP/IP (удалить/установить). Возможно, это последствия борьбы с вирусами.

    ОтветитьУдалить
  3. Я совсем недавно столкнулся со странным вылетом программы при старте. Оказалось - причина в статической линковке к одной dll-ке, которая отсутствовала у одного из клиентов.

    ОтветитьУдалить
  4. Анонимный2 июня 2010 г., 1:44

    > это не баг в явном виде
    Ну нет, что значит "не баг"? wsock32.dll не поддерживает сокеты версии 2.0, а только 1.1, которые были объявлены устаревшими уже лет 10 как.
    Нет, конечно, если Unicode-версия VCL появилась всего год назад, а MSLU (unicows.dll) вышла в 2001... вряд ли это станут исправлять. Время еще не пришло :)

    ОтветитьУдалить
  5. Анонимный18 мая 2011 г., 14:33

    Наткнулся на запись в процессе поиска а Гугле.
    Понятно, что уже прошел год, но в статье АНтона Григорьева
    http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1060#01
    в параграфе "Версии Windows Sockets" в первых абзацах (сразу после таблицы) есть кое-что насчет wsock32.dll и ws2_32.dll

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.