无法将DWORD转换为long unsigned int

时间:2015-03-27 06:12:59

标签: c++ pointers type-conversion

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;
}

3 个答案:

答案 0 :(得分:1)

要了解您所面临的问题,您必须明白,从概念上讲,这两种类型永远不会相同(除非它只是typedef)。 intlong根据语言有两种不同的类型。虽然您的实现可能具有相同的大小,但它们在所有实现中都不一定相同。如果您的目标是移植代码,那么假设它们的大小相同会导致问题。怎么样?

假设我们的实施sizeof(int)4sizeof(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)将意味着它{&#39} ll指向2000,如果您取消引用指针,即执行*l以阅读其中的内容,则会尝试读取long大小8通过尝试访问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);

如果你没有可移植性且确信intlong的大小相同,那么在您的实施方面,您可以另外通过-fpermissive以允许此转换GCC默认禁止。

答案 1 :(得分:0)

从错误消息中,tea_encrypt()的第一个参数是long unsigned int *类型。 (DWORD *)明确将pbBuffer转换为unsigned int *

虽然long unsigned intunsigned int有可能,但标准不要求这样做。如果它们不是您的实现的等效类型(在这种情况下是编译器),则指向一个的指针不能隐式转换为指向另一个的指针。

为了将第一个参数传递给函数,需要隐式转换(从unsigned int *long unsigned int *)。编译器抱怨,因为不允许隐式转换。

关于你做了什么,显而易见的是用(DWORD *)替换long unsigned int *(即将pbBuffer的值转换为函数所期望的指针)。这将使您的代码得到编译。

代码是否会正常运行是另一回事。您没有提供足够的上下文供任何人确定。

答案 2 :(得分:0)

检查功能tea_encrypt。该函数很可能期望unsigned long为32位(因为DWORD在Windows上,即使在Win64上),而unsigned long可能是您系统上的64位。你应该修复这个功能。最好的方法是将缓冲区的类型unsigned long更改为加密到uint32_t,以明确确定该类型的32位。 uint32_t *应该与DWORD*兼容,即使在您的系统上也是如此。