我正在为 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 标头的包装比Serial.h更复杂,因为您还需要返回和包装File对象。这可以使用标头中的结构声明来完成,实际类型在 .cpp 中定义。通过仅在标头中使用指向此类型的指针,您此时不需要定义结构。您也可以使用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 库只允许一次打开一个文件。