好的 - 一个提案 - 可能与您想要的有很大不同,但反馈会帮助您找到有用的东西。
对于同步“调用”,您希望您的应用模块发送所需驱动程序功能的指示以及无论多少参数,然后检索一些结果。这可以通过具有第二个不同的读/写流以通用方式实现,在该流上传输函数和值的编码。因此,假设驱动程序 API 包括:
string get_stuff(string x, int y, double d[]);
这不是代码 - 它是框架/应用可以打印/解析并可能用于验证数据是否已相应发送和使用的文本。
然后应用模块将“调用”作为函数标识符和输入流写入驱动程序,然后读取结果(假设应用模块具有保存所需参数值的同名变量)。
driver_api << "get_stuff " << escape(x) << ' ' << y << " [" << d.size() << "] ";
for (auto i = d.begin(); i != d.end(); ++i)
driver_api << ' ' << *i;
driver_api << '\n';
std::getline(driver_api, result);
创建一个自定义流包装器需要更多的工作(半小时?),它可以包装 driver_api 并在上面插入空格或其他分隔符/分隔符,支持容器流式传输,和/或以二进制形式,让您编写更清晰和/或更快的面向价值的上述版本,例如:
(driver_api << "get_stuff" << x << y << d) >> result;
您还可以编写普通的 C++ 函数来包装上面的内容以供应用程序模块调用:
string get_stuff(const std::string& x, int y, const std::vector<double>& d)
{
string result;
(driver_api_ << "get_stuff" << x << y << d) >> result;
return result;
}
在驱动程序方面,您将编写匹配的反序列化例程以从流中恢复应用模块指定的值。
对于特定的体系结构,您可以获取库以允许更方便地调用函数,利用调试信息或 ABI 知识等,而以上只需要标准 C++ 并且可以编写成可移植的(如果这样做,请注意一点字节序值的二进制序列化)。
EDIT - 二进制序列化示例(现在只是输出/运行但输出没有仔细检查有效性/大多数东西是固定宽度的,但字符串是 NUL 终止的,并且以大小为前缀的容器/不发送后续字段类型信息,但是很容易创建一个版本):
#include <iostream>
#include <vector>
#include <winsock2.h>
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned uint32_t;
class Binary_IOStream
{
public:
Binary_IOStream(std::istream& i, std::ostream& s) : i_(i), s_(s) { }
typedef Binary_IOStream This;
This& operator<<(int8_t x) { return write(x); }
This& operator<<(int16_t x) { return write(htons(x)); }
This& operator<<(int32_t x) { return write(htonl(x)); }
This& operator<<(uint8_t x) { return write(x); }
This& operator<<(uint16_t x) { return write(htons(x)); }
This& operator<<(uint32_t x) { return write(htonl(x)); }
This& operator<<(const std::string& s)
{ s_.write(s.c_str(), s.size() + 1); // include NUL, but could size-prefix
return *this; }
This& operator<<(double x) { return write(x); }
template <typename T>
This& operator<<(const std::vector<T>& v)
{ return write_range(v.begin(), v.end()); }
template <typename Iterator>
This& write_range(Iterator begin, Iterator end)
{
operator<<(std::distance(begin, end));
while (begin != end)
operator<<(*begin++);
return *this;
}
private:
template <typename T>
This& write(const T& t)
{ s_.write((const char*)&t, sizeof t); return *this; }
std::istream& i_;
std::ostream& s_;
};
int main()
{
Binary_IOStream bs(std::cin, std::cout);
bs << ('A' << 24) + ('b' << 16) + ('c' << 8) + 'D';
bs << "hello world!";
std::vector<double> v;
v.push_back(3.14);
v.push_back(2.72);
bs << v;
}