C ++从'char *'无效转换为'const unsigned char *'

我在NodeJS中编写我的项目,但我不得不使用C共享库。 正因为如此,我不得不使用Node.js插件。 调用C ++代码完美地工作,我也能够加载自定义库,并成功地调用两个C函数:一个给我的库的版本号,另一个方法基于JS提供的数据生成一个密钥。

我遇到的问题与生成的密钥有关。 我必须使用encryptdecrypt方法。

这是我用来存储密钥的variables:

 unsigned char generated_key[256]; 

这是生成密钥的function:

 extern "C" { #ifdef WIN32 VE_EXPORT int CALLBACK generate_key #else int generate_key #endif (char *variable_msg, /*!< variable seed */ char *shared_seed, /*!< shared seed */ unsigned char *generated_key, /*!< generated key */ unsigned int key_size); /*!< key size */ } 

这是一个使用键的function:

 extern "C" { #ifdef WIN32 VE_EXPORT int CALLBACK encrypt #else int encrypt #endif (const unsigned char * const plain_data, /*!< plain data */ const unsigned int plain_data_len, /*!< number bytes to be encrypted */ unsigned char *encrypted_data, /*!< encrypted data */ const unsigned int encrypted_data_size, /*!< size encrypted_data array */ unsigned int *encrypted_data_len, /*!< number of bytes encrypted */ const unsigned char * const key /*!< symmetric encryption key */ ); } 

当我尝试编译我得到的代码时:

 gyp info it worked if it ends with ok gyp info using node-gyp@3.4.0 gyp info using node@6.2.0 | linux | x64 gyp info spawn /usr/bin/python2 gyp info spawn args [ '/usr/local/lib/node_modules/node-gyp/gyp/gyp_main.py', gyp info spawn args 'binding.gyp', gyp info spawn args '-f', gyp info spawn args 'make', gyp info spawn args '-I', gyp info spawn args '/home/dgatti/sequr/sequr-experiments/CPP/Sequr/build/config.gypi', gyp info spawn args '-I', gyp info spawn args '/usr/local/lib/node_modules/node-gyp/addon.gypi', gyp info spawn args '-I', gyp info spawn args '/home/dgatti/.node-gyp/6.2.0/include/node/common.gypi', gyp info spawn args '-Dlibrary=shared_library', gyp info spawn args '-Dvisibility=default', gyp info spawn args '-Dnode_root_dir=/home/dgatti/.node-gyp/6.2.0', gyp info spawn args '-Dnode_gyp_dir=/usr/local/lib/node_modules/node-gyp', gyp info spawn args '-Dnode_lib_file=node.lib', gyp info spawn args '-Dmodule_root_dir=/home/dgatti/sequr/sequr-experiments/CPP/Sequr', gyp info spawn args '--depth=.', gyp info spawn args '--no-parallel', gyp info spawn args '--generator-output', gyp info spawn args 'build', gyp info spawn args '-Goutput_dir=.' ] make: Entering directory `/home/dgatti/sequr/sequr-experiments/CPP/Sequr/build' gyp info spawn make gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ] CXX(target) Release/obj.target/vertx/main.o ../main.cpp: In function 'void demo::VertxEncrypt(const v8::FunctionCallbackInfo<v8::Value>&)': ../main.cpp:127:102: error: invalid conversion from 'char*' to 'const unsigned char*' [-fpermissive] vertx_encrypt(cPayload, sizeof(cPayload), encMessage, sizeof(encMessage), &encLength, generated_key); ^ In file included from ../main.cpp:3:0: ../libvertx_encryption.h:79:7: error: initializing argument 1 of 'int vertx_encrypt(const unsigned char*, unsigned int, unsigned char*, unsigned int, unsigned int*, const unsigned char*)' [-fpermissive] int vertx_encrypt ^ make: *** [Release/obj.target/vertx/main.o] Error 1 make: Leaving directory `/home/dgatti/sequr/sequr-experiments/CPP/Sequr/build' gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 2 gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/node-gyp/lib/build.js:276:23) gyp ERR! stack at emitTwo (events.js:106:13) gyp ERR! stack at ChildProcess.emit (events.js:191:7) gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:204:12) gyp ERR! System Linux 3.10.0-327.13.1.el7.x86_64 gyp ERR! command "/usr/local/bin/node" "/usr/local/bin/node-gyp" "rebuild" gyp ERR! cwd /home/dgatti/sequr/sequr-experiments/CPP/Sequr gyp ERR! node -v v6.2.0 gyp ERR! node-gyp -v v3.4.0 gyp ERR! not ok 

这是我如何调用函数,现在我只是传递variables,但我尝试了很多不同的方式转换,铸造和改变。

 encrypt(cPayload, sizeof(cPayload), encMessage, sizeof(encMessage), &encLength, generated_key); 

我在C中编写了一个例子,一切正常,但是当我尝试在C ++中使用这个C函数时,事情就会刹车。 我有C的经验,但肯定不是用C ++。 我找了好几天才find解决办法,但是舅舅谷歌和伙伴堆栈无法解决问题。

我在找什么

  • 一个关键字,可以帮助我在我的search答案,
  • 或解决我的问题。

技术规格

  • gcc版本4.8.5 20150623(红帽4.8.5-4)(GCC)

完整的代码

这是我从NodeJS调用的C函数的完整代码:

 #include <node.h> #include <iostream> #include "lib_encryption.h" using namespace std; namespace demo { using v8::Exception; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Number; using v8::Object; using v8::String; using v8::Value; unsigned char generated_key[256]; unsigned int key_size = 32; unsigned int encLength; unsigned char encMessage[256] = {0}; // // This is the implementation of the "add" method // Input arguments are passed using the // const FunctionCallbackInfo<Value>& args struct // void GenerateKey(const FunctionCallbackInfo<Value>& args) { v8::String::Utf8Value param1(args[0]->ToString()); std::string strMessage = std::string(*param1); v8::String::Utf8Value param2(args[1]->ToString()); std::string strSecret = std::string(*param2); char cMessage[4]; strcpy(cMessage, strMessage.c_str()); char cSecret[11]; strcpy(cSecret, strSecret.c_str()); // // Creating the key // _generate_key(cMessage, cSecret, generated_key, key_size); // // 1. Create isolation storage // Isolate* isolate = args.GetIsolate(); // // 2. Save the value in to a isolate storage // Local<Value> str = String::NewFromUtf8(isolate, "Key done"); // // 3. Set the return value (using the passed in // FunctionCallbackInfo<Value>&) // args.GetReturnValue().Set(str); } void Encrypt(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); v8::String::Utf8Value param1(args[0]->ToString()); std::string payload = std::string(*param1); char cPayload[4]; strcpy(cPayload, payload.c_str()); for (int i=0; i<256; i++) { printf("%.2X ", generated_key[i]); } printf("\n"); encrypt(cPayload, sizeof(cPayload), encMessage, sizeof(encMessage), &encLength, generated_key); // // 1. Create isolation storage // // // 2. Save the value in to a isolate storage // Local<Value> str = String::NewFromUtf8(isolate, "Encrypt"); // // 3. Set the return value (using the passed in // FunctionCallbackInfo<Value>&) // args.GetReturnValue().Set(str); } // // * Initialize the object and expose the functions that need exposure. // void Init(Local<Object> exports) { NODE_SET_METHOD(exports, "GenerateKey", GenerateKey); NODE_SET_METHOD(exports, "Encrypt", Encrypt); } // // There is no semi-colon after NODE_MODULE as it's not a function // NODE_MODULE(, Init) } 

其他答案提到的背景,但不是具体问题,或者他们怀疑generated_key ,而是一个是好的。 我现在看到了molbdnilo的评论; 我以为有人提到它,但我似乎无法find它! [/编辑]所以这里是真正的原因:

对象cPayload是一个char[4] 。 像任何数组一样,它的名字在几个上下文中隐式地转换(通常俗称为“衰变”)为char * ,包括将其作为函数parameter passing时。 你把它传递给一个函数encrypt() ,在那个地方需要一个unsigned char * 。 但是char *unsigned char *是两个不同的types。 因此,错误。

回到背景,因为它值得指定。 char必须具有与signed charunsigned char相同的值范围,可以是可能被截断的static_cast ,并具有相同的别名权限 – 等等,但是在任何情况下,它都被认为是不同的types。 你可以通过检查3种types的结果来validation这个没有任何编译错误。

我不认为我知道哪部分代码有问题。 但我认为你正试图从char *转换为const unsigned char *,这是两种不同的types。 尝试将char *types更改为unsigned char *,或者可能在代码中无处不在使用unsigned char *。 这里有一个答案,它可以帮助你说, 简单字符,有符号字符和无符号字符是三种不同的types。

从char *转换为signed char *

默认的chartypes具有实现定义的签名,可以是有符号的或无符号的,具体取决于编译器。 因此,它不应该被用来存储除了string以外的任何东西。 切勿使用它来存储其他forms的数据。 它不一定与unsigned char兼容。

不编译的原因可能是因为C和C ++编译器之间char的签名性不同,但也可能是因为C ++比C有更严格和更好的types安全系统。虽然C编译器比较松散,可能会让代码通过而不会引发诊断信息,即使在C和C ++中混合这些types总是不好的做法。

只需改变为unsigned char或最好uint8_t和问题将消失。