0

After Effectsプラグインを開発していて、C++ネットワークライブラリであるraknetを統合しようとしています。raknetライブラリが呼び出してipv4アドレスを取得しようとしているとき

gethostbyname

次に、場所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++;
}

これが私が見ているもののいくつかの写真です。

http://jacobsgriffith.com/stackoverflow/noaccesserror.png

私はこれを読みましたが、ライブラリが間違って実装したようには見えません。 gethostbynameに関するMicrosoftドキュメント

h_addr_listとh_aliasesにカーソルを合わせると、が表示されます。

http://jacobsgriffith.com/stackoverflow/noaccess.jpg

誰かアイデアはありますか?なぜこれが失敗するのか私はこれが一般的な機能であると確信しています。

もう1つ、winsockとwinsock2のgethostbyname関数の実装に違いはありますか?

4

2 に答える 2

1

Windowsの実装がスレッドセーフではなく、各ホストにスレッドローカルストレージを使用していることに驚いています。しかし、とにかく...

getaddrinfoを使用してホスト名を解決するだけです。これはスレッドセーフであり、gethostnameの代わりとして使用されます。

ただし、最終的な目標は、ボックスのローカルIPアドレスを列挙することです。その場合は、UNIXではgetifaddrsを使用し、WindowsではGetAdaptersInfoとGetAdatperAddressesを組み合わせてローカルIPアドレスを列挙します。SIO_ADDRESS_LIST_QUERY ioctlは、Windowsのダミーソケットで使用することもできます。

于 2013-03-07T08:05:13.103 に答える
0

これが私が思いついた解決策です。どうやらgethostnameはスレッドセーフではありません。AfterEffectsはマルチスレッド化されています。

これを交換しました

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++;
}

これとともに

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++;
}

そして、これが私がそのルートに行った理由です。誰か反対?

gethostnameはスレッドセーフではありません

于 2013-03-07T07:39:24.630 に答える