簡體   English   中英

C ++從'char *'到'const unsigned char *'的無效轉換

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

我正在用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版本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 *轉換為帶符號的char *

默認的char類型具有實現定義的簽名,可以是有符號的也可以是無符號的,具體取決於編譯器。 因此,除了字符串之外,它永遠不能用於存儲任何內容。 切勿使用它存儲其他形式的數據。 它不一定與unsigned char兼容。

之所以不進行編譯,可能是因為char與C和C ++編譯器之間char變化所引起的簽名,但也可能是因為C ++具有比C更嚴格和更好的類型安全系統。即使在C和C ++中將這兩種類型混合在一起始終是一種不好的做法,但代碼卻不會產生診斷消息就可以通過。

只需更改為unsigned char或最好更改為uint8_t ,問題就會消失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM