c++从' char* '到' const unsigned char* '的无效转换

C++ invalid conversion from ‘char*’ to ‘const unsigned char*’

本文关键字:char 无效 转换 unsigned const c++      更新时间:2023-10-16

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

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

这是我用来存储键的变量:

unsigned char generated_key[256];

这是生成密钥的函数:

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 */
}

这是一个使用键的函数:

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

这就是我调用函数的方式,现在我只是按原样传递变量,但我尝试了许多不同的转换,转换和更改方法。

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

我用C写了一个例子,一切都很好,但是当我试图在c++中使用这个C函数时,事情就停止了。我有使用C语言的经验,但对c++毫无经验。我花了好几天的时间想找到一个解决方案,但是Google叔叔和Stack兄弟都没能想出一个解决方案。

我要找的

  • 一个可以帮助我搜索答案的关键字,
  • 或解决我的问题。
<标题>技术规范
  • gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (gcc)
<标题>完整代码

这是我从NodeJS调用访问C函数的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表示怀疑,但这一个是可以的。[edit]我现在看到molbdnilo的评论了;我以为有人提到过,但我似乎找不到它![/edit]所以真正的原因是:

对象cPayloadchar[4]。像任何数组一样,它的名称隐式地转换(通常通俗地称为'decays')为char *在一些上下文中,包括将其作为函数参数传递时。您将它传递给一个函数encrypt(),该函数在该位置需要一个unsigned char *。但是char *unsigned char *是两种不同的类型。因此出现了错误。

回到背景,因为它值得指定。char必须具有与signed charunsigned char相同的值范围,可以是static_cast,但可能被截断,并且具有相同的混叠能力-等等-但是,在任何情况下,它都被认为是一个不同的类型。您可以通过检查3种类型的typeid结果来验证这一点,而不会出现任何编译错误。

我猜我不明白代码的哪一部分有问题。但我认为你试图从char*转换为const unsigned char*,这是两种不同的类型。尝试将char*类型更改为unsigned char*,或者可能在代码中到处使用unsigned char*。这里有一个答案,它可能会对您有所帮助,上面说纯字符、有符号字符和无符号字符是三种不同的类型。

从char*到signed char*的转换

默认的char类型具有实现定义的签名,可以是有符号的也可以是无符号的,这取决于编译器。因此,它不应该用于存储字符串以外的任何东西。永远不要用它来存储其他形式的数据。它不一定与unsigned char兼容。

它不能编译的原因可能是因为C和c++编译器之间的char签名不同,但也可能是因为c++有比C更严格更好的类型安全系统。而C编译器更宽松,可能会让代码在没有引发诊断消息的情况下通过,尽管在C和c++中混合这些类型总是不好的做法。

只需更改为unsigned char或最好是uint8_t,问题就会消失。