Heim  >  Artikel  >  Backend-Entwicklung  >  Nutzung von APIs in C: ein praktischer Leitfaden für moderne Entwickler

Nutzung von APIs in C: ein praktischer Leitfaden für moderne Entwickler

Patricia Arquette
Patricia ArquetteOriginal
2024-11-24 08:10:10403Durchsuche

Consuming APIs in C: a practical guide for modern developers

Heutzutage ist die Nutzung von Web-APIs eine gängige Praxis für den Datenaustausch zwischen Anwendungen. Tutorials zur Verwendung von APIs in Sprachen wie JavaScript, Python oder PHP gibt es in Hülle und Fülle, doch C – das oft mit der Programmierung auf Systemebene in Verbindung gebracht wird – wird für diesen Zweck selten in Betracht gezogen. C ist jedoch durchaus in der Lage, API-Anfragen zu verarbeiten, was es zu einer brauchbaren Wahl für Szenarien wie Point-of-Sale-Systeme (PoS), IoT-Geräte oder eingebettete Anwendungen macht, in denen C aufgrund seiner Effizienz und einfachen Steuerung bereits verwendet wird.

In diesem Artikel wird untersucht, wie man APIs in C nutzt und dabei die libcurl-Bibliothek nutzt. Am Ende werden Sie verstehen, wie Sie mit C Daten von APIs abrufen und verarbeiten und warum dieser Ansatz auch in der modernen Entwicklung relevant ist.

Warum C zum Konsumieren von APIs verwenden?

Während höhere Sprachen die Webentwicklung dominieren, ist C immer noch eine praktische Wahl für die Nutzung von APIs in bestimmten Anwendungsfällen:

  • Leistung: C bietet hohe Leistung und minimalen Overhead und eignet sich daher für ressourcenbeschränkte Umgebungen wie IoT-Geräte.
  • Kontrolle: Die direkte Speicherverwaltung ermöglicht eine fein abgestimmte Optimierung, insbesondere für eingebettete Systeme.
  • Interoperabilität: Die weit verbreitete Verwendung von C bedeutet, dass es sich gut in Vorgänge auf Systemebene integrieren lässt, wie z. B. die Steuerung von Hardware, Sensoren oder anderen Peripheriegeräten.
  • Langlebigkeit: In C erstellte Anwendungen haben oft eine lange Lebensdauer, insbesondere in Branchen wie dem Einzelhandel oder der Fertigung.

Wir stellen vor: libcurl: das Tool für HTTP in C

Um APIs in C zu nutzen, ist libcurl die Bibliothek der Wahl. Es handelt sich um eine Open-Source-, portable und funktionsreiche Bibliothek zur Bearbeitung von Netzwerkanfragen über HTTP, HTTPS, FTP und mehr. Es unterstützt:

  • GET-, POST- und andere HTTP-Anfragen stellen.
  • Verwaltung von Headern und Authentifizierung.
  • Antworten effizient bearbeiten.

Grundlegende Schritte zum Nutzen einer API in C

Lassen Sie uns den Prozess der Nutzung einer API mit C durchgehen und uns dabei auf ein reales Beispiel für das Abrufen von JSON-Daten konzentrieren.

Einrichtung und Installation

Um libcurl verwenden zu können, müssen Sie es auf Ihrem System installieren. Bei den meisten Linux-Distributionen kann dies erfolgen mit:

sudo apt-get install libcurl4-openssl-dev

Unter Windows können Sie vorkompilierte Binärdateien von der libcurl-Website herunterladen: https://curl.se/download.html

Wenn Sie Homebrew unter macOS verwenden, können Sie es über
installieren

brew install curl

Strukturieren Sie Ihr C-Programm

Ein einfaches C-Programm zum Abrufen von Daten von einer API umfasst die folgenden Komponenten:

  • Libcurl wird initialisiert.
  • Konfigurieren der API-Anfrage (URL, HTTP-Methode, Header usw.).
  • Empfangen und Speichern der Antwort.
  • Ressourcen bereinigen.

Hier ist ein Beispielprogramm zum Abrufen von JSON-Daten von einer öffentlichen API:

sudo apt-get install libcurl4-openssl-dev

Schritte zum Ausführen

Speichern Sie den Code in einer Datei, z. B. get.c.
Kompilieren Sie es mit dem folgenden Befehl:

brew install curl

Führen Sie das kompilierte Programm aus:

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

Den Rückrufmechanismus in HTTP-Antworten mit libcurl verstehen

Wenn Sie mit libcurl arbeiten, um HTTP-Antworten in C zu verarbeiten, ist es wichtig, das Verhalten der Rückruffunktion zu verstehen. Die Rückruffunktion, die Sie zum Verarbeiten der Antwortdaten definieren, z. B. die ResponseCallback-Funktion, kann für eine einzelne HTTP-Antwort mehrmals aufgerufen werden. Hier erfahren Sie, warum und wie das funktioniert.

Warum wird der Rückruf mehrmals aufgerufen?

Der Rückrufmechanismus in libcurl ist darauf ausgelegt, Daten effizient und flexibel zu verarbeiten. Anstatt darauf zu warten, dass die gesamte Antwort heruntergeladen wurde, bevor sie verarbeitet wird, verarbeitet libcurl die Antwort in kleineren Blöcken und ruft Ihre Rückruffunktion auf, sobald jeder Block empfangen wird.

Dieses Verhalten ermöglicht:

  • Effiziente Speichernutzung: Durch die inkrementelle Verarbeitung von Blöcken vermeiden Sie die Notwendigkeit, im Voraus einen großen Speicherblock für die gesamte Antwort zuzuweisen.
  • Gestreamte Verarbeitung: Sie können jeden Block verarbeiten oder darauf reagieren, sobald er ankommt. Dies ist nützlich, um große Antworten zu streamen oder Daten in Echtzeit zu verarbeiten.

Wie funktioniert es?
Jedes Mal, wenn ein Datenblock vom Server empfangen wird, ruft libcurl Ihre Rückruffunktion auf. Die Größe jedes Blocks hängt von den Netzwerkbedingungen, den Puffergrößen und der internen Logik von libcurl ab.
Der Rückruf muss die Blöcke akkumulieren und letztendlich die vollständige Antwort rekonstruieren.

Hier ist eine Beispielsequenz:

  1. Der Server beginnt mit dem Senden der Antwort.
  2. libcurl empfängt den ersten Block und ruft den Rückruf auf.
  3. Der Rückruf verarbeitet oder speichert den Chunk.
  4. libcurl empfängt den nächsten Block und ruft den Rückruf erneut auf.
  5. Dieser Vorgang wird fortgesetzt, bis die gesamte Antwort eingegangen ist.

Schritt-für-Schritt-Erklärung des Quellcodes für die ResponseCallback-Funktion

Der ResponseCallback ist die Funktion, die aufgerufen wird, wenn Daten von libcurl empfangen werden.

Funktionsdeklaration

sudo apt-get install libcurl4-openssl-dev
  • void *contents: Dies ist ein Zeiger auf die vom Server empfangenen Daten. libcurl stellt diesen Puffer bereit und füllt ihn mit den heruntergeladenen Daten.
  • size_t size und size_t nmemb: Diese stellen die Größe jedes Speicherblocks (Size) und die Anzahl der Blöcke (nmemb) dar. Zusammen ergibt size * nmemb die Gesamtgröße der in diesem Block empfangenen Daten.
  • void *userp: Dies ist ein benutzerdefinierter Zeiger, der über curl_easy_setopt(curl, CURLOPT_WRITEDATA, ...) an die Callback-Funktion übergeben wird. In diesem Beispiel handelt es sich um einen Zeiger auf ein Strukturspeicherobjekt, das die vollständige Antwort speichert.

Berechnen Sie die Gesamtdatengröße

brew install curl

Dadurch wird die Gesamtgröße des aktuell empfangenen Datenblocks berechnet, indem die Größe eines Blocks (Größe) mit der Anzahl der Blöcke (nmemb) multipliziert wird.
Wenn der Server beispielsweise 8 Blöcke mit jeweils 256 Byte sendet, beträgt die Gesamtgröße 8 * 256 = 2048 Byte.

Auf Benutzerdaten zugreifen (Strukturspeicher)

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

Der Userp-Zeiger wird in eine Struktur Memory * umgewandelt. Diese Struktur wurde zuvor im Hauptprogramm übergeben und wird zum Sammeln der empfangenen Daten verwendet.

Die Struktur Memory ist definiert als:

./get
  • Antwort: eine dynamisch zugewiesene Zeichenfolge, die die heruntergeladenen Daten speichert.
  • Größe: die aktuelle Größe der Antwortzeichenfolge.

Speicher neu zuweisen

static size_t ResponseCallback(void *contents, size_t size, size_t nmemb, void *userp)

Ändert die Größe des Antwortpuffers, um den neuen Datenblock aufzunehmen:

  • mem->size: die aktuelle Größe des Puffers.
  • totalSize: Die Größe des neuen Blocks.
  • 1: Platz für den Nullterminator ( ), um daraus einen gültigen C-String zu machen.
  • realloc: Weist Speicher für den Antwortpuffer dynamisch neu zu.

Wenn die Zuweisung fehlschlägt, gibt realloc NULL zurück und der alte Speicher bleibt gültig.

Behandeln Sie Speicherzuordnungsfehler

size_t totalSize = size * nmemb;

Wenn die Speicherzuweisung fehlschlägt (also ptr NULL ist), geben Sie eine Fehlermeldung aus und geben Sie 0 zurück. Die Rückgabe von 0 signalisiert libcurl, die Übertragung abzubrechen.

Aktualisieren Sie den Puffer

struct Memory *mem = (struct Memory *)userp;
  • mem->response = ptr: Weisen Sie den neu zugewiesenen Speicher wieder dem Antwortzeiger zu.
  • memcpy: Kopieren Sie den neuen Datenblock aus dem Inhalt in den Puffer:
    • &(mem->response[mem->size]): Die Position im Puffer, an der die neuen Daten angehängt werden sollen (Ende der aktuellen Daten).
    • Inhalt: Die vom Server empfangenen Daten.
    • totalSize: Die Größe der zu kopierenden Daten.

Aktualisieren Sie die Gesamtgröße

struct Memory {
    char *response;
    size_t size;
};

Erhöhen Sie die Größe des Antwortpuffers, um die neue Gesamtgröße nach dem Anhängen des neuen Blocks widerzuspiegeln.

Beenden Sie die Antwortzeichenfolge mit Null

sudo apt-get install libcurl4-openssl-dev

Fügen Sie am Ende des Antwortpuffers einen Nullterminator hinzu, um daraus einen gültigen C-String zu machen.
Dadurch wird sichergestellt, dass die Antwort sicher als normale nullterminierte Zeichenfolge behandelt werden kann.

Gibt die Gesamtgröße zurück

brew install curl

Gibt die Anzahl der verarbeiteten Bytes zurück (totalSize).
Dies signalisiert libcurl, dass der Datenblock erfolgreich verarbeitet wurde.

Wann sollte man C für APIs wählen?

Verwenden Sie C zum Konsumieren von APIs, wenn:

  • Leistung zählt: C ist ideal für geschwindigkeitskritische Anwendungen.
  • Systemintegration: Sie müssen Netzwerkanfragen mit Hardwarevorgängen kombinieren (z. B. das Abrufen von Daten für ein PoS-System).
  • Eingebettete Systeme: Geräte mit begrenzten Ressourcen profitieren von der Effizienz von C.
  • Neugier und Erkundung: Manchmal verwenden Sie C einfach, weil Ihnen das Programmieren Spaß macht und Sie sich selbst herausfordern möchten, indem Sie eine Sprache auf niedrigerem Niveau für Aufgaben erforschen, die oft höheren Programmiersprachen vorbehalten sind. Es ist eine großartige Möglichkeit, Ihr Verständnis dafür zu vertiefen, wie die Dinge unter der Haube funktionieren!

Abschluss

Die Nutzung von APIs in C mag in der heutigen High-Level-Programmierwelt unkonventionell erscheinen, aber es ist ein leistungsstarkes Tool für Szenarien, die Leistung, Kontrolle und Integration mit Vorgängen auf Systemebene erfordern. Durch die Verwendung von Bibliotheken wie libcurl können Entwickler HTTP-Anfragen problemlos in C-Anwendungen integrieren und so die Lücke zwischen modernen APIs und traditioneller Programmierung auf Systemebene schließen.

Mit diesem Wissen können Sie C-Anwendungen erstellen, die nahtlos mit APIs interagieren und so beweisen, dass C auch in modernen Entwicklungsworkflows relevant bleibt.

Das obige ist der detaillierte Inhalt vonNutzung von APIs in C: ein praktischer Leitfaden für moderne Entwickler. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn