无法将 DWORD 转换为 long unsigned int
Cannot convert DWORD to long unsigned int
Error: Cannot convert DWORD* {aka unsigned int*} to 'long unsigned int*' for argument 1 to int tea_encrypt(long unsigned int*,)
代码如下:
bool CLZObject::Encrypt(DWORD * pdwKey)
{
if (!m_bCompressed)
{
assert(!"not compressed yet");
return false;
}
BYTE * pbBuffer = m_pbBuffer + sizeof(THeader);
m_pHeader->dwEncryptSize = tea_encrypt((DWORD *) pbBuffer, (const DWORD *) pbBuffer, pdwKey, m_pHeader->dwCompressedSize + 19);
return true;
}
从错误信息来看,tea_encrypt()
的第一个参数是long unsigned int *
类型。 (DWORD *)
明确地将 pbBuffer
转换为 unsigned int *
.
虽然 long unsigned int
和 unsigned int
是可能的,但这不是标准所要求的。如果它们与您的实现(即本例中的编译器)不是等效类型,则指向一个的指针不能隐式转换为指向另一个的指针。
为了将第一个参数传递给函数,需要隐式转换(从 unsigned int *
到 long unsigned int *
)。编译器抱怨,因为不允许隐式转换。
至于你做什么,显而易见的是用 long unsigned int *
替换 (DWORD *)
(即将 pbBuffer 的值转换为函数期望的指针)。这将使您的代码编译。
代码是否会正确运行是另一回事。您没有为任何人提供足够的上下文来确定这一点。
要了解您面临的问题,您必须了解两种类型在概念上绝非相同(除非它只是一个 typedef
)。根据语言,int
和 long
是两种不同的类型。尽管您的实施可能具有相同的大小,但它们不需要在所有实施中都相同。如果您的目标是可移植代码,假设它们大小相同会导致问题。怎么样?
假设我们有一个实现,其中 sizeof(int)
是 4
,sizeof(long)
是 8
。
int i = 0;
long *l = &i; // good that the compiler rejects this
如果允许这样做,那么您将进入 undefined behaviour。假设 i
位于内存位置 2000
,因为它是 4 字节大小,允许访问直到 2003
,因为该内存由程序拥有。程序(mer)不知道除此之外的内容,因此无法访问。
|<------------- i ------------->|
+-------+-------+-------+-------+-------+-------+-------+-------+
| 0x00 | 0x00 | 0x00 | 0x00 |unknown|unknown|unknown|unknown|
+-------+-------+-------+-------+-------+-------+-------+-------+
2000 2001 2002 2003 2004 2005 2006 2007
|<---------------------------- *l ----------------------------->| // oops!
由于 long
的大小为 8
,使 l
指向 i
的地址 (2000
) 将意味着它将指向2000
并且如果您取消引用指针,即执行 *l
以读取其中的内容,它将尝试读取大小为 8
的 long
,并尝试访问 2004到 2007 年,除了阅读 2000 年到 2003 年之外。因此导致您出现未定义的行为。
避免像显式转换(类型转换)这样的黑客行为,以干净的方式进行。使用临时的。
void need_long(long *data) { /* some code */ }
int i = 0;
long l = i; // temporary long to pass it to need_long
need_long(&l);
如果您可以接受不可移植性并且确信 int
和 long
大小相同,那么在您的实现中,您可以另外传递 -fpermissive
以允许此操作GCC 默认禁止的转换。
检查函数 tea_encrypt。此函数很可能期望 unsigned long
为 32 位(因为 DWORD 在 Windows 上,即使在 Win64 上也是如此),而 unsigned long
在您的系统上可能是 64 位。您应该修复该功能。最好的方法是将要加密的缓冲区的类型 unsigned long
更改为 uint32_t
以明确确定该类型的 32 位。 uint32_t *
应该与 DWORD*
兼容,即使在您的系统上也是如此。
Error: Cannot convert DWORD* {aka unsigned int*} to 'long unsigned int*' for argument 1 to int tea_encrypt(long unsigned int*,)
代码如下:
bool CLZObject::Encrypt(DWORD * pdwKey)
{
if (!m_bCompressed)
{
assert(!"not compressed yet");
return false;
}
BYTE * pbBuffer = m_pbBuffer + sizeof(THeader);
m_pHeader->dwEncryptSize = tea_encrypt((DWORD *) pbBuffer, (const DWORD *) pbBuffer, pdwKey, m_pHeader->dwCompressedSize + 19);
return true;
}
从错误信息来看,tea_encrypt()
的第一个参数是long unsigned int *
类型。 (DWORD *)
明确地将 pbBuffer
转换为 unsigned int *
.
虽然 long unsigned int
和 unsigned int
是可能的,但这不是标准所要求的。如果它们与您的实现(即本例中的编译器)不是等效类型,则指向一个的指针不能隐式转换为指向另一个的指针。
为了将第一个参数传递给函数,需要隐式转换(从 unsigned int *
到 long unsigned int *
)。编译器抱怨,因为不允许隐式转换。
至于你做什么,显而易见的是用 long unsigned int *
替换 (DWORD *)
(即将 pbBuffer 的值转换为函数期望的指针)。这将使您的代码编译。
代码是否会正确运行是另一回事。您没有为任何人提供足够的上下文来确定这一点。
要了解您面临的问题,您必须了解两种类型在概念上绝非相同(除非它只是一个 typedef
)。根据语言,int
和 long
是两种不同的类型。尽管您的实施可能具有相同的大小,但它们不需要在所有实施中都相同。如果您的目标是可移植代码,假设它们大小相同会导致问题。怎么样?
假设我们有一个实现,其中 sizeof(int)
是 4
,sizeof(long)
是 8
。
int i = 0;
long *l = &i; // good that the compiler rejects this
如果允许这样做,那么您将进入 undefined behaviour。假设 i
位于内存位置 2000
,因为它是 4 字节大小,允许访问直到 2003
,因为该内存由程序拥有。程序(mer)不知道除此之外的内容,因此无法访问。
|<------------- i ------------->|
+-------+-------+-------+-------+-------+-------+-------+-------+
| 0x00 | 0x00 | 0x00 | 0x00 |unknown|unknown|unknown|unknown|
+-------+-------+-------+-------+-------+-------+-------+-------+
2000 2001 2002 2003 2004 2005 2006 2007
|<---------------------------- *l ----------------------------->| // oops!
由于 long
的大小为 8
,使 l
指向 i
的地址 (2000
) 将意味着它将指向2000
并且如果您取消引用指针,即执行 *l
以读取其中的内容,它将尝试读取大小为 8
的 long
,并尝试访问 2004到 2007 年,除了阅读 2000 年到 2003 年之外。因此导致您出现未定义的行为。
避免像显式转换(类型转换)这样的黑客行为,以干净的方式进行。使用临时的。
void need_long(long *data) { /* some code */ }
int i = 0;
long l = i; // temporary long to pass it to need_long
need_long(&l);
如果您可以接受不可移植性并且确信 int
和 long
大小相同,那么在您的实现中,您可以另外传递 -fpermissive
以允许此操作GCC 默认禁止的转换。
检查函数 tea_encrypt。此函数很可能期望 unsigned long
为 32 位(因为 DWORD 在 Windows 上,即使在 Win64 上也是如此),而 unsigned long
在您的系统上可能是 64 位。您应该修复该功能。最好的方法是将要加密的缓冲区的类型 unsigned long
更改为 uint32_t
以明确确定该类型的 32 位。 uint32_t *
应该与 DWORD*
兼容,即使在您的系统上也是如此。