我今天遇到了最奇怪的问题。我正在网上做一个例子,而且我没有意外,它没有工作(他们几乎从不这样做)。我自己去修理它,但我似乎陷入了这个错误:
Error: Invalid Conversion from int* to unsigned int* [-fpermissive]
我理解这一点。我提供了int*
,它需要unsigned int*
。但是,我实际上并不知道为什么正在生成int*
。
这是解决问题的代码段:
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_length;
EVP_DigestFinal_ex(md_ctx, md_value, &md_length);
该函数调用的第三个参数&md_length
导致问题。查看该函数的文档调用(来自OpenSSL,如果它
问题,它期望参数为unsigned int*
类型,因为它需要一个地址(或者至少说明我正在使用的示例是如何使用的)它)
有趣的是,我认为&
运算符返回了unsigned int*
,因为返回int*
没有意义,因为计算机不具备他们记忆中的负面地址。
以下是我跟随的示例,如果您想看看:https://www.openssl.org/docs/crypto/EVP_DigestInit.html
以下是源代码,如果您想自己尝试一下。我怀疑你是否真的需要阅读它才能解决这个问题,但是在这里做到这一点并不会受到伤害。
源代码:
//* Description *//
// Title: Example
// Author: Boom Blockhead
// Example Program to Test OpenSSL
//* Libraries *//
#include <stdio.h>
#include <cstring>
#include <openssl/evp.h>
//* Namespaces *//
using namespace std;
//* Main Method *//
// Runs the Program and Interprets the Command Line
int main(int argc, char* argv[])
{
// Initialize the Messages
char msg1[] = "Test Message\n";
char msg2[] = "Hello World\n";
// Validate Argument Count
if(argc != 2)
{
printf("Usage: %s digestname\n", argv[0]);
exit(1);
}
// Determine Message Digest by Name
OpenSSL_add_all_digests();
const EVP_MD* md = EVP_get_digestbyname(argv[1]);
// Make sure a Message Digest Type was Found
if(md == 0)
{
printf("Unknown Message Digest %s\n", argv[1]);
exit(1);
}
// Create the Message Digest Context
EVP_MD_CTX* md_ctx = EVP_MD_CTX_create();
// Setup the Message Digest Type
EVP_DigestInit_ex(md_ctx, md, NULL);
// Add the Messages to be Digested
EVP_DigestUpdate(md_ctx, msg1, strlen(msg1));
EVP_DigestUpdate(md_ctx, msg2, strlen(msg2));
// Digest the Message
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_length;
EVP_DigestFinal_ex(md_ctx, md_value, &md_length); // <--- ERROR
// Destroy the Message Digest Context
EVP_MD_CTX_destroy(md_ctx);
// Print the Digested Text
printf("Digest is: ");
for(int i = 0; i < md_length; i++)
printf("%02x", md_value[i]);
printf("\n");
// Clean up the Message Digest
EVP_cleanup();
// Exit the Program
exit(0);
return 0;
}
此外,将(unsigned int*)
的显式演员似乎只会让事情变得更糟,因为我接下来会出现以下错误:
example.cpp:(.text+0x91): undefined reference to `OpenSSl_add_all_digests`
...
example.cpp:(.text+0x1ec): undefined reference to `EVP_cleanup`
基本上,它抱怨所有的OpenSSL功能。
最后,(再次,这只是为了给你们所有你可能需要的东西)我没有向编译器发送任何有趣的参数。我只是使用:
gcc example.cpp -o example.out
由于出现错误,example.out
实际上从未创建过。
答案 0 :(得分:3)
返回int *没有意义,因为计算机的内存中没有负地址。
您误解了类型名称的含义。
unsigned int*
是指向unsigned int
的指针。 unsigned不引用指针值。
因此,解决方案是将int更改为unsigned int。
答案 1 :(得分:2)
有趣的是,我认为&amp;运算符返回一个unsigned int *,因为返回int *没有意义,因为计算机的内存中没有负地址
它不是内存地址编号的签名(指针的基础值),它是存储在内存地址中的数据类型的签名,在这种情况下整数。
根据规范将md_length
更改为unsigned int
,它应该没问题。
答案 2 :(得分:2)
有趣的是,我认为&amp; operator返回一个unsigned int *,因为返回int *没有意义,因为计算机的内存中没有负地址。
那不是“有趣”;这是错的。
应用于T
类型对象的address-of运算符为您提供了T*
类型的指针。
周期。
T
是否为无符号或有符号类型不会进入,并且与涉及计算机是否具有负地址的哲学辩论无关。事实上,指针通常是签名,因为如果它们不是,那么当你试图获取两个地址之间的差异,或者在地址空间中向后走时,你很快就会陷入困境。
但这与在代码中使用术语unsigned
无关。