1

我正在为 Arduino Mega2560 编译某个 C 库。但是,我需要从我的 C 库中访问 SD.h 库。如果我将 C++ 编写为 C 包装器,这可能吗?

其他相关材料:

从 c http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html调用 c++ 代码

4

1 回答 1

2

您应该能够编写一个带有 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 库只允许一次打开一个文件。

于 2013-10-02T18:39:44.987 回答