我正在为Arduino Mega2560编译某个C库。但是,我需要从我的C库中访问SD.h库。如果我写一个C ++到C包装器,这可能吗?
其他相关材料:
calling c++ code from c http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
答案 0 :(得分:2)
你应该能够编写一个带有C接口的包装器库,它调用C ++库。
这里的关键是在构建为C ++时使用extern "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库只允许一次打开。< / p>