2010-11-22 33 views
0

LibCurl kullanarak bu kodu (Sockets eklentisiyle bir betik dili kullanarak) C++ 'ya çevirmek istiyorum. LibCurl'u daha önce bir kez kullanmıştım, bu yüzden başka ne ihtiyacım olduğuna dair bir kayıpta yaşıyorum. Kafam karıştıran ana noktam, sadece curl_easy_setopt (curl, CURLOPT_HTTPHEADER, header) kullanabilmem; Bunu göndermek için veya soketi çıkarmaya ihtiyacım varsa, o zaman bunu gönder.C++ LibCurl GET from get

İşte ...

public OnSocketConnected(Handle:socket, any:friendId) 
{ 
    decl String:CommunityId[32]; 
    FriendIDToCommunityId(friendId, CommunityId, sizeof(CommunityId)); 

    decl String:query[2048]; 
    decl String:cookieString[100]; 
    decl String:inviterString[32]; 
    decl String:groupString[32]; 

    GetConVarString(cookie, cookieString, sizeof(cookieString)); 
    GetConVarString(inviter, inviterString, sizeof(inviterString)); 
    GetConVarString(group, groupString, sizeof(groupString)); 


    Format(query, sizeof(query), "GET /actions/GroupInvite?type=groupInvite&inviter=%s&invitee=%s&group=%s HTTP/1.1\r\nHost: steamcommunity.com\r\nConnection: close\r\nCookie: steamLogin=%s\r\n\r\n", inviterString, CommunityId, groupString, cookieString); 
    SocketSend(socket, query); 
    LogMessage("%s", query); 
} 

komut dosyasından ilgili pasajı ve burada şimdiye kadar C++ ne var. İlk önce soketi çıkarmaya ihtiyacım var gibi görünüyor ama ağ kodlama konusunda yetkin değilim, bu yüzden buradan nereye gitmem gerektiğinden tam olarak emin değilim.

void InviteToGroup(const char *szUserSteamID, const char *szInviterSteamID, const char *steamUser, const char *steamPass) 
{ 
    CURL *curl; 
    CURLcode res, result; 
    //int sockfd; /* socket */ 
    char errorBuffer[CURL_ERROR_SIZE]; 

    const char *szUserID = GetCommunityID(szUserSteamID); // User's Steam Community ID 
    const char *szInviterID = GetCommunityID(szInviterSteamID); // Inviter's Steam Community ID 
    char *szGroupID = ""; 
    GetGroupCommunityID(1254745, &szGroupID); // Group Steam Community ID 
    const char *szCookie = "76561198018111441%7C%7CC7D70E74A3F592F3E130CCF4CAACD4A7B9CAD993"; // Steam Community Login Cookie 

    char *buffer = new char[512]; 

    // Create the GET request 
    struct curl_slist *headers = NULL; 
    headers = curl_slist_append(headers, "GET /actions/GroupInvite?type=groupInvite&inviter="); 
    snprintf(buffer, sizeof(buffer), "%s&invitee=%s&group=%s ", szInviterID, szUserID, szGroupID); 
    headers = curl_slist_append(headers, buffer); 
    headers = curl_slist_append(headers, "HTTP/1.1\r\nHost: steamcommunity.com\r\nConnection: close\r\nCookie: "); 
    snprintf(buffer, sizeof(buffer), "steamLogin=%s\r\n\r\n", szCookie); 
    headers = curl_slist_append(headers, buffer); 

    delete buffer; 

    // Init CURL 
    curl = curl_easy_init(); 

    if(curl) 
    { 
     curl_easy_setopt(curl, CURLOPT_URL, "https://www.steamcommunity.com"); 
     curl_easy_setopt(curl, CURLOPT_PORT, 443); // Check this before using 
     curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer); 
     //curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); // No transfer, just extract the socket 

     // Find out if we need to use Proxy stuff here 

     char *userpass = new char[64]; 
     snprintf(userpass, sizeof(userpass), "%s:%s", steamUser, steamPass); 
     curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); 
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 

     // Attempt to Connect the Steam Community Server 
     res = curl_easy_perform(curl); 

     if (res == CURLE_OK) 
      Msg("Connected Successfully!\n"); 
     else 
      Msg("Connection Failed! Error: %s\n", errorBuffer); 

     // Close the connection 
     curl_easy_cleanup(curl); 
    } 
} 

cevap

0

Bu nedenle, C++'nız yanlış olduğu için düzeltmeler burada kodunuzun çalışmadığı anlamına gelir.

sizeof (char *) işaretçinin boyutudur, dizginin uzunluğu değil. Yani snprintf, null terminatörü içerecek olan 32 bitlik bir sistemde 4 karaktere kadar yazdıracaktır, böylece sadece 3 uzunluğunda bir dizge elde edeceksiniz.

"Yeterince büyük olmalı" arabellek onu yeni ile ayırmayın. Snprintf'i kullanmak istiyorsanız std :: vektörünü kullanabilirsiniz, ardından yazılacak gerçek dizenin uzunluğu olan snprintf'nin dönüş değerini kontrol edin ve ardından gerekirse tampon boyutunu artırın (dönüş değeri + 1'e).

vector<char> buffer; 
size_t required = 511; 
do 
{ 
    buffer.resize(required + 1); 
    required = snprintf(&buffer[0], buffer.size(), formatstr, ...); 
} 
while(required >= buffer.size()); 

otomatik olarak yapacağız vektörü olarak (bu arada yanlış yaptım) sonunda gerek "ücretsiz" tampon yoktur.

Artık işlevi & arabelleğe geçirin [0], boş sonlandırılmış bir dizeye işaret edecek ve API bir const char * yerine bir char * gerektiriyorsa yazılabilir. (libcurl, curl_easy_setopt öğesinin 3. parametresi olarak "herhangi bir şeyi" iletebilmenizi sağlar. Bu nedenle, std :: string'i yanlışlıkla iletirseniz, derleyici tarafından uyarılmadığınız için dikkatli olmanız gerekir. std :: vector).