例: 文字列インターニングライブラリ
C++ ヘッダー: interner.hpp
#ifndef INTERNER_HPP
#define INTERNER_HPP
#include <string>
#include <unordered_set>
class StringInterner {
std::unordered_set<std::string> strings;
public:
// インターン化された文字列へのポインタを返す(interner の存続期間中は有効)
const char* intern(const char* s) {
auto [it, _] = strings.emplace(s);
return it->c_str();
}
size_t count() const {
return strings.size();
}
};
#endif
C ヘッダーファイル: interner.h
// interner.h(FFI 用の C API)
#ifndef INTERNER_H
#define INTERNER_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct StringInterner StringInterner;
StringInterner* interner_new(void);
void interner_free(StringInterner* interner);
const char* interner_intern(StringInterner* interner, const char* s);
size_t interner_count(const StringInterner* interner);
#ifdef __cplusplus
}
#endif
C++ 実装(interner.cpp)
#include "interner.hpp"
#include "interner.h"
extern "C" {
StringInterner* interner_new(void) {
return new StringInterner();
}
void interner_free(StringInterner* interner) {
delete interner;
}
const char* interner_intern(StringInterner* interner, const char* s) {
return interner->intern(s);
}
size_t interner_count(const StringInterner* interner) {
return interner->count();
}
}
これは少し大きめの例です。文字列インターナーのラッパーを書いてください。不透明ポインタの作成方法については、以下のコードを説明して直接示すか、あるいは学習者に追加で調べてもらう必要があります。
推奨される解答
#![allow(unused)] fn main() { // Copyright 2026 Google LLC // SPDX-License-Identifier: Apache-2.0 use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::os::raw::c_char; #[repr(C)] pub struct StringInternerRaw { _opaque: [u8; 0], _pin: PhantomData<(*mut u8, std::marker::PhantomPinned)>, } unsafe extern "C" { fn interner_new() -> *mut StringInternerRaw; fn interner_free(interner: *mut StringInternerRaw); fn interner_intern( interner: *mut StringInternerRaw, s: *const c_char, ) -> *const c_char; fn interner_count(interner: *const StringInternerRaw) -> usize; } }
raw ラッパーを書いたら、次に学習者に安全なラッパーを作成してもらってください。