오늘날 웹 API를 사용하는 것은 애플리케이션 간 데이터 교환을 위한 일반적인 관행입니다. JavaScript, Python 또는 PHP와 같은 언어로 API를 사용하는 방법에 대한 자습서는 많지만 시스템 수준 프로그래밍과 관련된 C는 이러한 목적으로 거의 고려되지 않습니다. 그러나 C는 API 요청을 완벽하게 처리할 수 있으므로 PoS(Point of Sale) 시스템, IoT 장치 또는 임베디드 애플리케이션과 같은 시나리오에서 실행 가능한 선택이 됩니다. 여기서 C는 효율성과 낮은 수준의 제어를 위해 이미 사용되고 있습니다.
이 기사에서는 libcurl 라이브러리를 활용하여 C에서 API를 사용하는 방법을 살펴봅니다. 마지막에는 C를 사용하여 API에서 데이터를 가져오고 처리하는 방법과 이 접근 방식이 현대 개발에도 적합한 이유를 이해하게 됩니다.
고급 언어가 웹 개발을 지배하지만 C는 여전히 특정 사용 사례에서 API를 사용하기 위한 실용적인 선택입니다.
C에서 API를 사용하려면 libcurl이 적합한 라이브러리입니다. HTTP, HTTPS, FTP 등을 통한 네트워크 요청을 처리하기 위한 오픈 소스, 이식성 및 기능이 풍부한 라이브러리입니다. 다음을 지원합니다:
JSON 데이터를 가져오는 실제 사례를 중심으로 C를 사용하여 API를 사용하는 과정을 살펴보겠습니다.
libcurl을 사용하려면 시스템에 libcurl을 설치해야 합니다. 대부분의 Linux 배포판에서는 다음을 사용하여 이 작업을 수행할 수 있습니다.
sudo apt-get install libcurl4-openssl-dev
Windows에서는 libcurl 웹사이트(https://curl.se/download.html)에서 미리 컴파일된 바이너리를 다운로드할 수 있습니다.
macOS에서 Homebrew를 사용하는 경우 다음을 통해 설치할 수 있습니다
brew install curl
API에서 데이터를 가져오는 간단한 C 프로그램에는 다음 구성 요소가 포함됩니다.
다음은 공개 API에서 JSON 데이터를 가져오는 예제 프로그램입니다.
sudo apt-get install libcurl4-openssl-dev
코드를 파일(예: get.c.)에 저장하세요.
다음 명령을 사용하여 컴파일하십시오.
brew install curl
컴파일된 프로그램 실행:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> // Struct to hold response data struct Memory { char *response; size_t size; }; // Callback function to handle the data received from the API static size_t ResponseCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t totalSize = size * nmemb; struct Memory *mem = (struct Memory *)userp; printf(". %zu %zu\n", size, nmemb); char *ptr = realloc(mem->response, mem->size + totalSize + 1); if (ptr == NULL) { printf("Not enough memory to allocate buffer.\n"); return 0; } mem->response = ptr; memcpy(&(mem->response[mem->size]), contents, totalSize); mem->size += totalSize; mem->response[mem->size] = '<pre class="brush:php;toolbar:false">gcc get.c -o get -lcurl'; return totalSize; } int main() { CURL *curl; CURLcode res; struct Memory chunk; chunk.response = malloc(1); // Initialize memory chunk.size = 0; // No data yet curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if (curl) { // Set URL of the API endpoint char access_token[] = "your-access-token"; char slug[] = "home"; char version[]= "draft"; char url[256]; snprintf(url, sizeof(url), "https://api.storyblok.com/v2/cdn/stories/%s?version=%s&token=%s", slug, version, access_token); // Print the URL printf("URL: %s\n", url); // initializing libcurl // setting the URL curl_easy_setopt(curl, CURLOPT_URL, url ); // Follow redirect curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Set callback function to handle response data curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ResponseCallback); // Pass the Memory struct to the callback function curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); // Perform the HTTP GET request res = curl_easy_perform(curl); // Check for errors if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else { printf("Response data size: %zu\n", chunk.size); //printf("Response data: \n%s\n", chunk.response); } // Cleanup curl_easy_cleanup(curl); } // Free allocated memory free(chunk.response); curl_global_cleanup(); return 0; }
C에서 HTTP 응답을 처리하기 위해 libcurl을 사용할 때 콜백 함수의 동작을 이해하는 것이 중요합니다. ResponseCallback 함수와 같이 응답 데이터를 처리하기 위해 정의한 콜백 함수는 단일 HTTP 응답에 대해 여러 번 호출될 수 있습니다. 이것이 작동하는 이유와 방법은 다음과 같습니다.
libcurl의 콜백 메커니즘은 데이터를 효율적이고 유연하게 처리하도록 설계되었습니다. 전체 응답을 처리하기 전에 다운로드되는 것을 기다리는 대신, libcurl은 응답을 더 작은 청크로 처리하여 각 청크가 수신될 때 콜백 함수를 호출합니다.
이 동작으로 인해 다음이 가능합니다.
어떻게 작동하나요?
서버로부터 데이터 덩어리가 수신될 때마다 libcurl은 콜백 함수를 호출합니다. 각 청크의 크기는 네트워크 상태, 버퍼 크기 및 libcurl의 내부 논리에 따라 다릅니다.
콜백은 청크를 축적하여 궁극적으로 전체 응답을 재구성해야 합니다.
다음은 예시 시퀀스입니다.
ResponseCallback은 libcurl이 데이터를 수신할 때 호출되는 함수입니다.
sudo apt-get install libcurl4-openssl-dev
brew install curl
한 블록의 크기(size)에 블록 수(nmemb)를 곱하여 현재 수신된 데이터 청크의 전체 크기를 계산합니다.
예를 들어 서버가 각각 256바이트의 블록 8개를 전송하는 경우 totalSize는 8 * 256 = 2048바이트가 됩니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> // Struct to hold response data struct Memory { char *response; size_t size; }; // Callback function to handle the data received from the API static size_t ResponseCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t totalSize = size * nmemb; struct Memory *mem = (struct Memory *)userp; printf(". %zu %zu\n", size, nmemb); char *ptr = realloc(mem->response, mem->size + totalSize + 1); if (ptr == NULL) { printf("Not enough memory to allocate buffer.\n"); return 0; } mem->response = ptr; memcpy(&(mem->response[mem->size]), contents, totalSize); mem->size += totalSize; mem->response[mem->size] = '<pre class="brush:php;toolbar:false">gcc get.c -o get -lcurl'; return totalSize; } int main() { CURL *curl; CURLcode res; struct Memory chunk; chunk.response = malloc(1); // Initialize memory chunk.size = 0; // No data yet curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if (curl) { // Set URL of the API endpoint char access_token[] = "your-access-token"; char slug[] = "home"; char version[]= "draft"; char url[256]; snprintf(url, sizeof(url), "https://api.storyblok.com/v2/cdn/stories/%s?version=%s&token=%s", slug, version, access_token); // Print the URL printf("URL: %s\n", url); // initializing libcurl // setting the URL curl_easy_setopt(curl, CURLOPT_URL, url ); // Follow redirect curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Set callback function to handle response data curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ResponseCallback); // Pass the Memory struct to the callback function curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); // Perform the HTTP GET request res = curl_easy_perform(curl); // Check for errors if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else { printf("Response data size: %zu\n", chunk.size); //printf("Response data: \n%s\n", chunk.response); } // Cleanup curl_easy_cleanup(curl); } // Free allocated memory free(chunk.response); curl_global_cleanup(); return 0; }
userp 포인터는 구조체 Memory *로 캐스팅됩니다. 이 구조체는 메인 프로그램 초기에 전달되었으며 수신된 데이터를 축적하는 데 사용됩니다.
구조체 Memory는 다음과 같이 정의됩니다.
./get
static size_t ResponseCallback(void *contents, size_t size, size_t nmemb, void *userp)
새 데이터 청크를 수용하도록 응답 버퍼 크기를 조정합니다.
할당이 실패하면 realloc은 NULL을 반환하고 이전 메모리는 유효한 상태로 유지됩니다.
size_t totalSize = size * nmemb;
메모리 할당이 실패하면(즉 ptr은 NULL임) 오류 메시지를 인쇄하고 0을 반환합니다. 0을 반환하면 libcurl에 전송을 중단하라는 신호가 전달됩니다.
struct Memory *mem = (struct Memory *)userp;
struct Memory { char *response; size_t size; };
새 청크를 추가한 후 새 전체 크기를 반영하도록 응답 버퍼의 크기를 늘립니다.
sudo apt-get install libcurl4-openssl-dev
응답 버퍼 끝에 null 종결자를 추가하여 유효한 C 문자열로 만듭니다.
이렇게 하면 응답이 일반 null 종료 문자열로 안전하게 처리될 수 있습니다.
brew install curl
처리된 바이트 수(totalSize)를 반환합니다.
이는 데이터 청크가 성공적으로 처리되었음을 libcurl에 알립니다.
다음과 같은 경우 API를 사용하기 위해 C를 사용합니다.
C에서 API를 사용하는 것은 오늘날의 고급 프로그래밍 세계에서는 색다른 것처럼 보일 수 있지만 성능, 제어 및 시스템 수준 작업과의 통합이 필요한 시나리오를 위한 강력한 도구입니다. libcurl과 같은 라이브러리를 사용하면 개발자는 HTTP 요청을 C 애플리케이션에 쉽게 통합하여 최신 API와 기존 시스템 수준 프로그래밍 간의 격차를 해소할 수 있습니다.
이러한 지식을 바탕으로 API와 원활하게 상호 작용하는 C 애플리케이션을 구축하여 최신 개발 워크플로에서도 C가 여전히 관련성을 유지한다는 것을 입증할 수 있습니다.
위 내용은 C에서 API 사용: 현대 개발자를 위한 실용적인 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!