Arduino Mega2560 用の特定の C ライブラリのコンパイルに取り組んでいます。ただし、C ライブラリ内から SD.h ライブラリにアクセスする必要があります。C++ から C へのラッパーを作成した場合、これは可能ですか?
その他の関連資料:
c http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.htmlからの C++ コードの呼び出し
C++ ライブラリを呼び出す C インターフェイスを備えたラッパー ライブラリを作成できるはずです。
ここで重要なのはextern "C"
、C++ としてビルドするときに を使用して、C++ 部分が C 関数を C++ ではなく C として呼び出すようにすることです。
SD ヘッダーは、 Fileオブジェクトも返してラップする必要があるため、 Serial.hなどよりもラップが複雑です。これは、実際の型が .cpp で定義されたヘッダーで struct 宣言を使用して実行できます。ヘッダーでこの型へのポインターのみを操作することにより、この時点で構造体を定義する必要はありません。代わりにポインターを使用することもできますが、タイプ セーフが失われるため、これは避けます。void*
SD_c_iface.h
#ifndef SD_C_IFACE_H
#define SD_C_IFACE_H
#include <Arduino.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Wrapper around File type */
typedef struct _SD_File SD_File;
size_t SD_File_write(SD_File* file, const uint8_t *buf, size_t size);
/* TODO Wrap all required File functions */
/* Wrapper around SD type */
boolean SD_begin(uint8_t csPin);
void SD_open(const char *filename, uint8_t mode, SD_File** file);
/* TODO Wrap all required SD functions */
#ifdef __cplusplus
}
#endif
#endif
SD_c_iface.cpp
#include "SD_c_iface.h"
#include "SD.h"
struct _SD_File
{
File f;
};
size_t SD_File_write(SD_File* file, const uint8_t *buf, size_t size)
{
return (file) ? file->f.write(buf, size) : 0;
}
boolean SD_begin(uint8_t csPin)
{
SD.begin(csPin);
}
void SD_open(const char *filename, uint8_t mode, SD_File** file)
{
if (!file)
return;
*file = new _SD_File();
(*file)->f = SD.open(filename, mode);
}
// TODO Add more function wrappers
上記の方法は、物事をラップする一般的な方法です。たとえば、SD.h ライブラリでは一度に 1 つのファイルしか開くことができないため、物事を単純化し、一度に 1 つのファイルのみを開くことができます。