当前位置:  开发笔记 > 编程语言 > 正文

将指针转换为整数

如何解决《将指针转换为整数》经验,为你挑选了5个好方法。

我正在尝试将现有代码调整为64位机器.主要问题是在一个函数中,前一个编码器使用void*参数,该参数在函数本身中转换为合适的类型.一个简短的例子:

void function(MESSAGE_ID id, void* param)
{
    if(id == FOO) {
        int real_param = (int)param;
        // ...
    }
}

当然,在64位机器上,我收到错误:

error: cast from 'void*' to 'int' loses precision

我想纠正这个问题,以便它仍然可以在32位机器上运行并且尽可能干净.任何的想法 ?



1> Alex..:

我会说这是现代的C++方式.

#include 
void *p;
auto i = reinterpret_cast(p);

编辑:

整数的正确类型

所以将指针存储为整数的正确方法是使用uintptr_tintptr_t类型.(另请参阅C99的 cppreference 整数类型).

这些类型在C99和stdC++ 11 的命名空间中定义(请参阅C++的整数类型).

C++ 11(及以后)版本

#include 
std::uintptr_t i;

C++ 03版

extern "C" {
#include 
}

uintptr_t i;

C99版

#include 
uintptr_t i;

正确的铸造操作员

在C中只有一个强制转换,并且在C++中使用C强制转换是不受欢迎的(所以不要在C++中使用它).在C++中有不同的演员阵容.reinterpret_cast是这次转换的正确演员(另见此处).

C++ 11版

auto i = reinterpret_cast(p);

C++ 03版

uintptr_t i = reinterpret_cast(p);

C版

uintptr_t i = (uintptr_t)p; // C Version

相关问题

什么是uintptr_t数据类型


唯一正确提到reinterpret_cast的答案
这应该被标记为选定的答案,因为它提供了如何在**C和C++**中投射的所有细节.

2> Milan Babušk..:

使用intptr_tuintptr_t.

为确保以便携方式定义,您可以使用以下代码:

#if defined(__BORLANDC__)
    typedef unsigned char uint8_t;
    typedef __int64 int64_t;
    typedef unsigned long uintptr_t;
#elif defined(_MSC_VER)
    typedef unsigned char uint8_t;
    typedef __int64 int64_t;
#else
    #include 
#endif

只需将其放在某个.h文件中,并将其包含在您需要的任何位置.

或者,你可以下载微软的版本stdint.h从文件在这里,或者使用从便携式一个在这里.



3> Richard Cord..:

'size_t'和'ptrdiff_t'需要与您的架构相匹配(无论它是什么).因此,我认为不应该使用'int',而应该能够使用'size_t',它在64位系统上应该是64位类型.

这个讨论unsigned int vs size_t更详细一些.


虽然size_t通常足以容纳指针,但情况并非如此.最好找到一个stdint.h头文件(如果你的编译器还没有),并使用uintptr_t.
指针不一定适合`size_t`.
不幸的是,`size_t`的唯一约束是它必须保存任何`sizeof()`的结果.这不一定使它在x64上成为64位.[另见](http://stackoverflow.com/a/1089204/762488)

4> moonshadow..:

使用uintptr_t为您的整数类型.



5> Jonathan Lef..:

有几个答案指出uintptr_t#include 作为"解决方案".也就是说,我建议,答案的一部分,但不是整个答案.您还需要查看使用FOO的消息ID调用函数的位置.

考虑这段代码和编译:

$ cat kk.c
#include 
static void function(int n, void *p)
{
    unsigned long z = *(unsigned long *)p;
    printf("%d - %lu\n", n, z);
}

int main(void)
{
    function(1, 2);
    return(0);
}
$ rmk kk
        gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith \
            -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \
            -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE kk.c -o kk 
kk.c: In function 'main':
kk.c:10: warning: passing argument 2 of 'func' makes pointer from integer without a cast
$

您将观察到调用位置(in main())存在问题- 将整数转换为没有强制转换的指针.您将需要分析您function()的所有用法,以了解如何将值传递给它.function()如果写入调用,我的内部代码将起作用:

unsigned long i = 0x2341;
function(1, &i);

由于您的编写方式可能不同,因此需要查看调用函数的点,以确保使用显示的值是有意义的.别忘了,你可能会发现一个潜在的错误.

此外,如果您要格式化void *参数的值(转换后),请仔细查看标题(而不是stdint.h- inttypes.h提供服务stdint.h,这是不寻常的,但C99标准说[标题]标题包括标题和通过托管实现提供的附加功能扩展它,并在格式字符串中使用PRIxxx宏.

此外,我的注释严格适用于C而不是C++,但您的代码位于C++的子集中,可以在C和C++之间移植.我的评论适用的机会是公平的.


我想你错过了我的问题.代码将整数的值存储在指针中.并且代码的那部分正在相反(例如,提取被写为*作为*指针的整数的值).
推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有