Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Проблема с WinSock2


Автор: andrew_121 29.5.2009, 14:52
Программа с использованием сокетов. Компилируется, линкуется, а при попытке запустить, сообщает:
Точка входа в процедуру inet_pton не найдена в библиотеке ws2_32.dll
Т.е. Я так понимаю, что сама длл-ка есть, но в ней нет этого экспорта. Почему же он есть в библиотеке экспорта?

Автор: REZiaMIX 29.5.2009, 15:34
inet_addr не тоже самое?

Автор: andrew_121 29.5.2009, 16:31
Цитата(REZiaMIX @  29.5.2009,  15:34 Найти цитируемый пост)
inet_addr не тоже самое? 

Думаю нет. Да и вопрос не в этом.

Автор: azesmcar 29.5.2009, 16:36
http://msdn.microsoft.com/en-us/library/cc805844(VS.85).aspx
хочу обратить внимание на это
Цитата

Minimum supported client    Windows Vista
Minimum supported server    Windows Server 2008
Header    Ws2tcpip.h
Library    Ws2_32.lib
DLL    Ws2_32.dll
Unicode and ANSI names    InetPtonW (Unicode) and InetPtonA or inet_pton (ANSI)

Автор: andrew_121 29.5.2009, 17:09
azesmcar, Гм... А что вместо нее использовать? inet_addr как-то не то smile 

Автор: azesmcar 29.5.2009, 17:13
andrew_121
смотря что нужно smile
это разные функции.
inet_addr - конвертирует в IN_ADDR, плюс он не работает с Ipv6.
Можно самому написать конвертер (или еще проще - скопировать из сорсов юникса)

http://www.koders.com/c/fid74A647B73741DDD374D5478366A00584E8740D43.aspx
http://www.samba.org/rsync/doxygen/head/inet__pton_8c-source.html
вот сорс-код

Автор: andrew_121 29.5.2009, 17:30
azesmcar, Спасибо! Ща попробую.

Автор: andrew_121 29.5.2009, 18:03
Не помогло.
В моем коде эта функция используется всего однажды. Я ее переименовал, и подсунул из сорца. Возможно она используется другими функциями из Sockets2.

Какие еще предложения?

Автор: REZiaMIX 29.5.2009, 19:11
попробовать скачать библиотеку winsock2.dll от висты , вручную загрузить(getprocaddress) из нее функцию и переопределить дефайном(или перехватить).
Извращенно , но может прокатит :В

библиотека называеца ws2_32.dll

Автор: andrew_121 29.5.2009, 19:17
Я так и сделал. Скачал. Положил в каталог с программой. Но нет, не хочет ее использовать.
Вот думаю подменить стандартную виндовскую на эту, хз что произойдет smile 

Автор: REZiaMIX 29.5.2009, 19:18
Цитата(andrew_121 @ 29.5.2009,  19:17)
Я так и сделал. Скачал. Положил в каталог с программой. Но нет, не хочет ее использовать.
Вот думаю подменить стандартную виндовскую на эту, хз что произойдет smile

а если сделать FreeLibrary , а потом LoadLibrary с полным путем?

Автор: REZiaMIX 29.5.2009, 19:36
Можно сделать LoadLibrary правильной DLL;
потом обявить самому эту функцию, и GetProcAddress(...).
Тогда 100% функция будет что надо ,но не факт что результат в общем будет правильным, и не факт что функция из dll висты заработает

По хорошему - тут надо искать другое , не каверзное решение.

Автор: azesmcar 29.5.2009, 19:40
Цитата(andrew_121 @  29.5.2009,  18:03 Найти цитируемый пост)
Не помогло.
В моем коде эта функция используется всего однажды. Я ее переименовал, и подсунул из сорца. Возможно она используется другими функциями из Sockets2.

подробнее пожалуйста. Что должно было произойти, и что произошло.

Цитата(andrew_121 @  29.5.2009,  19:17 Найти цитируемый пост)
Вот думаю подменить стандартную виндовскую на эту, хз что произойдет smile  

лучше не надо
а вообще - подробнее о задаче, люди до появления висты писали программы под виндоуз и не жаловались на отсутствие этой функции. Почему она вдруг стала так жизненно важна?

Автор: andrew_121 29.5.2009, 20:23
Перегрузился в Лин, подменил на вистовскую версию этой либы. Экран смерти. Вернул все как прежде.

Цитата(REZiaMIX @  29.5.2009,  19:18 Найти цитируемый пост)
а если сделать FreeLibrary , а потом LoadLibrary с полным путем? 

    Можно попробовать. Но я полагаю, что ХР версия этой длл-ки статически подгружается. Получится ли ее выгрузить...надо пробовать.

Цитата(REZiaMIX @  29.5.2009,  19:36 Найти цитируемый пост)
Можно сделать LoadLibrary правильной DLL;
потом обявить самому эту функцию, и GetProcAddress(...).
Тогда 100% функция будет что надо ,но не факт что результат в общем будет правильным, и не факт что функция из dll висты заработает

И это пробовал. Но как я понял, эту же функцию, наверное, используют другие функции из Socks2. Я выше писал. Цитирую:
Цитата
В моем коде эта функция используется всего однажды. Я ее переименовал, и подсунул из сорца. Возможно она используется другими функциями из Sockets2.


Цитата(azesmcar @  29.5.2009,  19:40 Найти цитируемый пост)
подробнее пожалуйста. Что должно было произойти, и что произошло.

Было: 
Цитата
Программа с использованием сокетов. Компилируется, линкуется, а при попытке запустить, сообщает:
Точка входа в процедуру inet_pton не найдена в библиотеке ws2_32.dll

Последовал вашему совету: 
Цитата
Можно самому написать конвертер (или еще проще - скопировать из сорсов юникса)

Все так и осталось.

Цитата(azesmcar @  29.5.2009,  19:40 Найти цитируемый пост)
лучше не надо

Уже понял)))
Цитата(azesmcar @  29.5.2009,  19:40 Найти цитируемый пост)
а вообще - подробнее о задаче, люди до появления висты писали программы под виндоуз и не жаловались на отсутствие этой функции. Почему она вдруг стала так жизненно важна?

Согласен. Программа в Лине работает. Нужно чтоб работала в Винде.

Вот smile 

Автор: azesmcar 29.5.2009, 20:33
Цитата(andrew_121 @  29.5.2009,  20:23 Найти цитируемый пост)
Было: 

Было, не то что я спрашивал

Цитата(andrew_121 @  29.5.2009,  20:23 Найти цитируемый пост)
Согласен. Программа в Лине работает. Нужно чтоб работала в Винде.

хотя тут я ответ получил smile 
Я собственно не понял, в чем проблема была? скопировал из сорсов линукса, 
1. функция откомпилировалась? Да/Нет.
2. тестировалась отдельно от проекта? Да/Нет.

Автор: andrew_121 30.5.2009, 10:57
Цитата(azesmcar @  29.5.2009,  20:33 Найти цитируемый пост)
Я собственно не понял, в чем проблема была? скопировал из сорсов линукса, 
1. функция откомпилировалась? Да/Нет.
2. тестировалась отдельно от проекта? Да/Нет.

1. Да.
2. Да.


Но при запуске все равно сообщает: Точка входа в процедуру inet_pton не найдена в библиотеке ws2_32.dll

Автор: azesmcar 30.5.2009, 19:05
Цитата(andrew_121 @  30.5.2009,  10:57 Найти цитируемый пост)
Но при запуске все равно сообщает: Точка входа в процедуру inet_pton не найдена в библиотеке ws2_32.dll 

Следовательно в программе используется эта функция (не написанная, а именно виндоузовская), либо ее использует другая библиотека которую используешь ты.
1. Надо проверить, а точно ли она не используется в коде. Переименовать функцию и все ее вызовы, откомпилировать, проверить.
2. Если все еще не работает, проверить под дебагером кто использует функцию.

Автор: andrew_121 30.5.2009, 19:27
Цитата(azesmcar @  30.5.2009,  19:05 Найти цитируемый пост)
1. Надо проверить, а точно ли она не используется в коде. Переименовать функцию и все ее вызовы, откомпилировать, проверить.

Во всем проекте, всего однажды.



Цитата(azesmcar @  30.5.2009,  19:05 Найти цитируемый пост)
2. Если все еще не работает, проверить под дебагером кто использует функцию.

Как? Чё дебагить то?

Автор: azesmcar 30.5.2009, 19:37
Цитата(andrew_121 @  30.5.2009,  19:27 Найти цитируемый пост)
Как? Чё дебагить то? 

Программу свою
http://www.ollydbg.de/

Это конечно в том случае, если логически вычислить виновника не получается.

Автор: andrew_121 30.5.2009, 21:01
azesmcar, Так, минуточку! В моем коде эта функция используется всего однажды. Я ее заменил сорцом. Значит ее мне дебагить ненужно.
Так, вы что, предлагаете дебагить до тех пор пока я не встречу сию функцию? И что мне это даст? Я же не могу ее в длл-ке заменить. Или...?

Автор: azesmcar 30.5.2009, 21:11
Цитата(andrew_121 @  30.5.2009,  21:01 Найти цитируемый пост)
azesmcar, Так, минуточку! В моем коде эта функция используется всего однажды. Я ее заменил сорцом. Значит ее мне дебагить ненужно.

Если в своем коде ты ее заменил, значит ошибка выдаватся не должна. А если выдается - значит либо не везде заменил, либо используешь другую библитеку, которая использует эту функцию..Кто-то же на не ссылается что ошибка вылетает. Для начала я бы порекомендовал сделать полный ребилд проекта. Если не поможет, искать дебагером виновника. Т.е. запустить под дебагером и посмотреть, кто именно требует эту функцию. Сперва вычислить, а потом думать как исправить.

Автор: andrew_121 30.5.2009, 21:54
Буду пробовать...

Автор: REZiaMIX 31.5.2009, 20:06
ws2_32.dll линкуется динамически(и для каждого процесса она "своя").
я бы попробовал перехватить ее и заменить на свою. Должно поидее прокатить.
т.е. DWORD addr = (DWORD)&inet_pton;
Самое простое - заменить первые 5 байт , на jump на свою функцию.

Да и вообще , дал бы код программы где используется эта функция - наверняка ее очень легко заменить аналогом.
Врядли winsock2 будет её использовать без указаний извне smile 

Автор: andrew_121 31.5.2009, 21:35
Цитата(REZiaMIX @  31.5.2009,  20:06 Найти цитируемый пост)
Самое простое - заменить первые 5 байт , на jump на свою функцию.

Подробней пожалуйста....



Цитата(REZiaMIX @  31.5.2009,  20:06 Найти цитируемый пост)
Да и вообще , дал бы код программы где используется эта функция - наверняка ее очень легко заменить аналогом.

Вот:
Код

/* Connect a client socket to a server socket */
bool Socket::connect(const LString& host, const int port) {
    if (!is_valid()) { return false; }

    m_addr.sin_family = AF_INET;
    m_addr.sin_port = htons(port);

    int status = inet_pton(AF_INET, host.c_str(), (unsigned char*)&m_addr.sin_addr);

#ifndef WIN32
    if (errno == EAFNOSUPPORT) { return false; }
#endif
    status = ::connect(m_sock, (sockaddr *) &m_addr, sizeof(m_addr));

    return (status == 0);
}


Автор: REZiaMIX 31.5.2009, 23:59
Код


SOCKET getOutgoingSocket(char * addr,unsigned int PORT)
{
        SOCKET sock;
    sock = socket(AF_INET,SOCK_STREAM,0);
    if (sock == INVALID_SOCKET) 
        repsys::report("Error at socket(): %ld\n", WSAGetLastError());

    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst = NULL;


    if (inet_addr(addr)!=INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(addr);
    else
      if (hst=gethostbyname(addr))
          ((unsigned long *)&dest_addr.sin_addr)[0]=
            ((unsigned long **)hst->h_addr_list)[0][0];
    hst=gethostbyname(addr);
    if(hst == NULL)
        repsys::report("DNS fail or invalid addr.\n");

    if(connect(sock,(sockaddr *)&dest_addr,sizeof(dest_addr)) )
                repsys::report("connect fail.\n");
    
    return sock;
}



Аналогичный код , + разрешение dns если адрес является не IP , а именем домена.
Используется inet_addr. repsys::report - функция лог ошибок.
Думаю ошибка возникает в коде не по причине inet_pton.

Какого рода вообще ошибка , не проще ли пройтись дебагом по программе , и посмотреть где что и как?
Думаю не идет коннект?!?!
(это моя старая функция , есть баг когда два раза вызывается gethostbyname, исправить просто булевой переменной где надо)
inet_addr вроде отличается только тем , что не справиться с ipv6(пока еще рано о нем думать по моему мнению).

Добавлено @ 00:09
Да и... Другими функциями из sockets2 (win xp) использоваться она ну никак не будет , если ее нету!

Так что надо искать ошибку в другом месте.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)