C++:invalid conversion from 'unsigned char *' to 'const char *'
最近使用node的串口库发现很慢,自己用c++写了个驱动使用node去调用它并测试通过,速度也很快,最初版本记录下:
https://pan.baidu.com/s/1MRtebBZZpsHFVzWP7GGhng
test.js
var test = require('./build/Release/test'); test.ArduinoDevice('test', function(data) { console.log(data); });
gyp配置:
{ "targets": [ { "target_name": "test", "sources": [ "test.cc"] } ] }
test.cc
#include <node.h> #include <v8.h> #include <stdio.h> #include <unistd.h> //Used for UART #include <fcntl.h> //Used for UART #include <termios.h> //Used for UART #include <string.h> using namespace v8; // 传入了两个参数,args[0] 字符串,args[1] 回调函数 void hello(const FunctionCallbackInfo<Value>& args) { // 使用 HandleScope 来管理生命周期 Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); /////////////////////////////////////////////////////////////////// int uart0 = -1; printf("----------starting-------------------\n"); uart0 = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode if (uart0 == -1) { printf("Error - Unable to open UART. Ensure it is not in use by another application\n"); } struct termios options; tcgetattr(uart0, &options); options.c_cflag = B9600 | CS8 | CLOCAL | CREAD; options.c_iflag = IGNPAR; options.c_oflag = 0; options.c_lflag = 0; tcflush(uart0, TCIFLUSH); tcsetattr(uart0, TCSANOW, &options); //----- TX BYTES ----- unsigned char tx_buffer[20]; unsigned char *p_tx_buffer; unsigned char *p_tx_buffer2; unsigned char str[] = "closel\0"; // p_tx_buffer = &tx_buffer[0]; // *p_tx_buffer++ = 'o'; // *p_tx_buffer++ = 'p'; // *p_tx_buffer++ = 'e'; // *p_tx_buffer++ = 'n'; // *p_tx_buffer++ = 'l'; printf("--1--\n"); p_tx_buffer2 = &tx_buffer[0]; printf("--then str is %s and strlen is %d--\n",(const char*)str,strlen((const char*)str)); //printf("%s",strlen(str)); for(int i=0;i<strlen(reinterpret_cast<const char*>(str));i++){ printf("--for inner 1 is %d--\n",i); *p_tx_buffer2++ = str[i]; printf("--for inner 2 is %d--\n",i); //printf("%s",str[i]); } printf("--2--\n"); if (uart0 != -1) { int count = write(uart0, &tx_buffer[0], (p_tx_buffer2 - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write if (count < 0) { printf("UART TX error\n"); } close(uart0); } /////////////////////////////////////////////////////////////////// // 判断参数格式和格式 if (args.Length() < 2 || !args[0]->IsString()) { isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, "Wrong arguments"))); return; } // callback, 使用Cast方法来转换 Local<Function> callback = Local<Function>::Cast(args[1]); Local<Value> argv[1] = { // 拼接String String::Concat(Local<String>::Cast(args[0]), String::NewFromUtf8(isolate, " fuck world")) }; // 调用回调, 参数: 当前上下文,参数个数,参数列表 callback->Call(isolate->GetCurrentContext()->Global(), 1, argv); } // 相当于在 exports 对象中添加 { hello: hello } void init(Handle<Object> exports) { NODE_SET_METHOD(exports, "ArduinoDevice", hello); } // 将 export 对象暴露出去 // 原型 `NODE_MODULE(module_name, Initialize)` NODE_MODULE(test, init);
unsigned char *foo(); std::string str; str.append(reinterpret_cast<const char*>(foo()));
reinterpret_cast用法:
reinterpret_cast<type-id> (expression)
type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。
reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。例如:int *n= new int ; double *d=reinterpret_cast<double*> (n); 在进行计算以后,d 包含无用值。这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d,没有进行必要的分析。因此,需要谨慎使用 reinterpret_cast。
IBM的C++指南里倒是明确告诉了我们reinterpret_cast可以,或者说应该在什么地方用来作为转换运算符:
- 从指针类型到一个足够大的整数类型
- 从整数类型或者枚举类型到指针类型
- 从一个指向函数的指针到另一个不同类型的指向函数的指针
- 从一个指向对象的指针到另一个不同类型的指向对象的指针
- 从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
- 从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针
事实上reinterpret_cast的使用并不局限在上边所说的几项的,任何类型的指针之间都可以互相转换,都不会得到编译错误。上述列出的几项,可能 是Linux下reinterpret_cast使用的限制,也可能是IBM推荐我们使用reinterpret_cast的方式。
以雷霆击碎黑暗