问题描述
我正在为浏览器扩展实现 native host。我围绕 std::cin
而不是 C 风格的 getchar()
这里的问题是 std::cin
没有以二进制模式打开,这对基于 Windows 的主机有影响,因为 Chrome 浏览器不适用于 Windows 样式 \r\n
因此我必须以二进制方式阅读它模式。
要以二进制模式读取,我必须使用 _setmode(_fileno(stdin),_O_BINARY);
我的 IDE 找不到 _fileno
的定义,我发现解决方法是使用以下宏,
#if !defined(_fileno)
#define _fileno(__F) ((__F)->_file)
#endif
但是,我对这个宏不够自信。我认为有问题,但我使用的是最新的 MinGW 编译器,但不确定为什么没有定义。
更新:该函数似乎在 __STRICT_ANSI__
后面,我不知道如何禁用它。
无论如何,程序编译良好,浏览器启动它,当我从浏览器发送消息时,应用程序能够读取消息的长度,当它尝试读取内容时,std::cin.read()
操作插入缓冲区向量没有任何内容,消息也不是空终止的,但我认为这不会导致问题。
我还尝试在没有阅读的情况下向浏览器发送一条虚拟消息,但它似乎冻结了浏览器。
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#ifdef __WIN32
#include <fcntl.h>
#include <io.h>
#endif
#if !defined(_fileno)
#define _fileno(__F) ((__F)->_file)
#endif
enum class Platforms {
macOS = 1,Windows = 2,Linux = 3
};
Platforms platform;
#ifdef __APPLE__
constexpr Platforms BuildOS = Platforms::macOS;
#elif __linux__
constexpr Platforms BuildOS = Platforms::Linux;
#elif __WIN32
constexpr Platforms BuildOS = Platforms::Windows;
#endif
void sendMessage(std::string message) {
auto *data = message.data();
auto size = uint32_t(message.size());
std::cout.write(reinterpret_cast<char *>(&size),4);
std::cout.write(data,size);
std::cout.flush();
}
int main() {
if constexpr(BuildOS == Platforms::Windows) {
// Chrome doesn't deal well with Windows style \r\n
_setmode(_fileno(stdin),_O_BINARY);
_setmode(_fileno(stdout),_O_BINARY);
}
while(true) {
std::uint32_t messageLength;
// First Four contains message legnth
std::cin.read(reinterpret_cast<char*>(&messageLength),4);
if (std::cin.eof())
{
break;
}
std::vector<char> buffer;
// Allocate ahead
buffer.reserve(std::size_t(messageLength) + 1);
std::cin.read(&buffer[0],messageLength);
std::string message(buffer.data(),buffer.size());
sendMessage("{type: 'Hello World'}");
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)