Reputation: 1476
I'm developing an after effects plugin and I'm trying to integrate raknet which is a c++ network library. When the raknet library is trying to get the ipv4 address by calling
gethostbyname
it then throws an error access violation reading location 0xFFFFFFFFFFFFFFFF
int idx=0;
char ac[ 80 ];
int err = gethostname( ac, sizeof( ac ) );
(void) err;
RakAssert(err != -1);
struct hostent *phe = gethostbyname( ac );
if ( phe == 0 )
{
RakAssert(phe!=0);
return ;
}
for ( idx = 0; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
{
if (phe->h_addr_list[ idx ] == 0)
break;
memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[ idx ], sizeof(struct in_addr));
}
while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
{
addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
idx++;
}
Here are some pictures of what I see.
http://jacobsgriffith.com/stackoverflow/noaccesserror.png
I've read this and it doesn't look like the library implemented it wrong. Microsoft Documentation On gethostbyname
When I hover over h_addr_list and h_aliases I get .
http://jacobsgriffith.com/stackoverflow/noaccess.jpg
Anybody have any ideas? Why is this failing I'm pretty sure this is a common function.
Another thing, is there any difference between the implementations of the gethostbyname function from winsock and winsock2?
Upvotes: 0
Views: 914
Reputation: 104514
I'm surprised the Windows implementation isn't thread safe and using thread local storage for each hostent. But in any case...
Just use getaddrinfo to resolve host names. It's thread safe and is meant as a replacement for gethostname.
But your ultimate goal is to enumerate the local IP addresses on the box. In that case, just use getifaddrs on UNIX and the combination of GetAdaptersInfo and GetAdatperAddresses on Windows to enumerate local IP addresses. You can also use the SIO_ADDRESS_LIST_QUERY ioctl with a dummy socket on Windows.
Upvotes: 1
Reputation: 1476
This is the solution I came up with. Aparently gethostname is not thread safe. After effects is multithreaded.
I replaced this
int idx=0;
char ac[ 80 ];
int err = gethostname( ac, sizeof( ac ) );
(void) err;
RakAssert(err != -1);
struct hostent *phe = gethostbyname( ac );
if ( phe == 0 )
{
RakAssert(phe!=0);
return ;
}
for ( idx = 0; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
{
if (phe->h_addr_list[ idx ] == 0)
break;
memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[ idx ],sizeof(struct in_addr));
}
while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
{
addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
idx++;
}
with this
int idx=0;
struct addrinfo* feed_server = NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
getaddrinfo("localhost", NULL, &hints, &feed_server);
struct addrinfo *res;
for(res = feed_server; res != NULL; res = res->ai_next) {
struct sockaddr_in* saddr = (struct sockaddr_in*)res->ai_addr;
//char* ipv4Str = inet_ntoa(saddr->sin_addr);
memcpy(&addresses[idx].address.addr4.sin_addr, &saddr->sin_addr, sizeof(struct in_addr));
idx++;
}
while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS) {
addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
idx++;
}
And this is why I went that route. Anybody object?
Upvotes: 0