🎃

【C 言語】【Zig】【PHP FFI】curl のバージョン番号を表示する

2024/04/19に公開

Debian で libcurl4-openssl-dev を入れた。

sudo apt install libcurl4-openssl-dev

curl_version を使う。単純なコードだが Zig などほかの言語で利用するときにヘッダーやライブラリが読み込まれているかどうかを確認するために使える

#include <stdio.h>
#include <curl/curl.h>

int main(void)
{
  printf("%s\n", curl_version());
}

実行結果は次のとおり

zig run test.c -lc -lcurl
libcurl/7.88.1 OpenSSL/3.0.11 zlib/1.2.13 brotli/1.0.9 zstd/1.5.4
libidn2/2.3.3 libpsl/0.21.2 (+libidn2/2.3.3) libssh2/1.10.0
nghttp2/1.52.0 librtmp/2.3 OpenLDAP/2.5.13

curl_version_info を通して個別のライブラリのバージョン番号を取り出すこともできる

#include<stdio.h>
#include<curl/curl.h>

int main(void)
{
  curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW);
  printf("libcurl version %u.%u.%u\n",
         (ver->version_num >> 16) & 0xff,
         (ver->version_num >> 8) & 0xff,
         ver->version_num & 0xff);
}

ほかに nghttp2 のバージョン番号を文字列形式で取り出してみよう

#include<stdio.h>
#include<curl/curl.h>

int main(void)
{
  curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
  printf("nghttp2 version %s\n", data->nghttp2_version);
}

続いて Zig のコードを書く。curl_version() を使えばいろいろなライブラリのバージョン番号をまとめて表示できる。

const std = @import("std");
const print = std.debug.print;
const cURL = @cImport({
    @cInclude("curl/curl.h");
});

pub fn main() !void {
  print("{s}\n", .{cURL.curl_version()});
}

ビルドは次の通り

zig runtest.c -lc -lcurl

curl_version_info を使って個別のライブラリのバージョン番号を得ることができる。C 言語の構造体のポインターのメンバーにアクセスするにはアスタリクス(*)を使う

const std = @import("std");
const print = std.debug.print;
const cURL = @cImport({
    @cInclude("curl/curl.h");
});

pub fn main() !void {
  const data = cURL.curl_version_info(cURL.CURLVERSION_NOW);
  print("{s}\n", .{data.*.version});
}

最後に PHP FFI を試す

$ffi = FFI::cdef("
  char *curl_version(void);
");

var_dump(
  FFI::string($ffi->curl_version())
);

curl_version_info の使用例を示す。PHP FFI は includedefine などのプリプロセッサをサポートしないため、大量の定数を使う必要がある curl を直接使うのはやりづらい。curl_version_info_data は必要な部分だけ抜粋したコードである。インストールされていないライブラリの項目があるとエラーになった。

$ffi = FFI::cdef('
typedef enum {
  CURLVERSION_FIRST,    /* 7.10 */
  CURLVERSION_SECOND,   /* 7.11.1 */
  CURLVERSION_THIRD,    /* 7.12.0 */
  CURLVERSION_FOURTH,   /* 7.16.1 */
  CURLVERSION_FIFTH,    /* 7.57.0 */
  CURLVERSION_SIXTH,    /* 7.66.0 */
  CURLVERSION_SEVENTH,  /* 7.70.0 */
  CURLVERSION_EIGHTH,   /* 7.72.0 */
  CURLVERSION_NINTH,    /* 7.75.0 */
  CURLVERSION_TENTH,    /* 7.77.0 */
  CURLVERSION_ELEVENTH, /* 7.87.0 */
  CURLVERSION_TWELFTH,  /* 8.8.0 */
  CURLVERSION_LAST /* never actually use this */
} CURLversion;

struct curl_version_info_data {
  CURLversion age;
  const char *version;
  unsigned int version_num;
};

struct curl_version_info_data {
  CURLversion age;
  const char *version;
  unsigned int version_num;
};

typedef struct curl_version_info_data curl_version_info_data;

curl_version_info_data *curl_version_info(CURLversion age);
');

$info = $ffi->curl_version_info($ffi->CURLVERSION_TWELFTH);


var_dump(
  $info->version
);

Discussion