简体   繁体   English

如何使用C在64位平台中将void *转换为int?

[英]How to cast a void* to int in 64-bit platforms, using C?

I am a linguist in charge of a C program, so please excuse me if the answer is obvious. 我是负责C程序的语言学家,所以如果答案很明显,请原谅。 I have the following code: 我有以下代码:

typedef struct array_s {
  (...)
  void **value;
} array_t;
typedef array_t *array_pt;

array_pt array_new (int size) {
  (...)
  array->value = (void **)malloc(size*sizeof(void *));
}

void* array_get (array_pt arr, int i) {
  return arr->value[i];
}

int main () {
  int a = 1234;
  int *ptr = &a;

  array_pt array = array_new(1);
  array_add(array, ptr);

  printf("%i\n", (int)array_get(array, 0));
}

It is supposed to provide me with a multi-purpose array (for storing int and char* , if I understood I can only use void ), and I guess there are no problems of allocating/freeing. 它应该为我提供一个多用途的数组(用于存储intchar* ,如果我理解只能使用void ),而且我认为分配/释放没有问题。 However, I cannot get to cast it into anything useful (ie, get back the "original" int/char*), and for what I understood it could be because I am in a 64-bit system and the size of a pointer to void is different from the size of a pointer to int / char* (the program is supposed to be used in both 64 and 32 bit systems). 但是,我无法将其转换为任何有用的内容(即,获取“原始” int / char *),并且据我了解,这可能是因为我处于64位系统中,并且指向的指针大小void与指向int / char*的指针的大小不同(该程序应该在64位和32位系统中都使用)。 I tried using intptr_t and other alternatives, to no luck. 我尝试使用intptr_t和其他替代方法,但是没有运气。

How can I be sure that the code will accept any data type and work on both 32 and 64 bit systems? 我如何确定该代码将接受任何数据类型并在32位和64位系统上都能正常工作? Thank you. 谢谢。

EDIT: 编辑:

Sorry for not adding array_add , here it is: 很抱歉没有添加array_add ,这里是:

unsigned int array_add (array_pt array, void *ptr) {
  (...) // get the next index
  // allocate if needed
  array->value = (void **)realloc(array->value, array->size*sizeof(void *));

  array->value[index] = p;
}

You need to dereference your pointer: 您需要取消引用指针:

int* temp = array_get(array, 0);
printf("%i\n", *temp);

However, I strongly recommend avoiding this type of approach. 但是,我强烈建议您避免使用这种方法。 You're basically giving away the small amount of help the compiler in C will normally provide - purposefully trying to make non-typesafe arrays. 您基本上是在放弃使用C编译器通常提供的少量帮助-故意尝试制作非类型安全的数组。

You need to decide what is it you are trying to do in this case. 您需要确定在这种情况下要执行的操作。

(1) If you want to use your void * array to store int values ( actual int forcefully converted to void * ), then you should add these int values to the array as follows (1)如果要使用void *数组存储int值(将实际 int强制转换为void * ),则应按以下方式将这些int值添加到数组中

int a = 1234; 

array_pt array = array_new(1); 
array_add(array, (void *) a); 

and then get them back from array as follows 然后从数组中将它们取回,如下所示

int a = (int) array_get(array, 0); 
printf ("%d\n", a);

or simply 或简单地

printf ("%d\n", (int) array_get(array, 0)));

That last part is exactly what you did, but you got the first part wrong. 最后一部分正是您所做的,但是您弄错了第一部分。

This is a cast-based approach, which is ugly in many ways, but it has certain practical value, and it will work assuming void * is large enough to hold an int . 这是基于转换的方法,在许多方面都很丑陋,但是具有一定的实用价值,并且在void *足够大以容纳int This is the approach that might depend on the properties of 32- and 64-bit systems. 这种方法可能取决于32位和64位系统的属性。

(2) If you want to use your void * array to store int * values (pointers to int ), then you should add these int values to the array as follows (2)如果要使用void *数组存储int *值(指向int指针),则应按以下方式将这些int值添加到数组中

int a = 1234; 

array_pt array = array_new(1); 
array_add(array, &a); 

and then get them back from array as follows 然后从数组中将它们取回,如下所示

int *pa = array_get(array, 0); 
printf ("%d\n", *pa);

or simply 或简单地

printf ("%d\n", *(int *) array_get(array, 0));

This approach is perfectly safe from any portability problems. 这种方法对于任何可移植性问题都是绝对安全的。 It has no 32- or 64-bit issues. 它没有32位或64位问题。 A void * pointer is guaranteed to safely hold a int * pointer or any other data pointer. 保证void *指针可以安全地保存int *指针或任何其他数据指针。

If that was your intent, then you got the first part right and the last part wrong. 如果这是您的意图,那么您得出的第一部分是正确的,最后一部分是错误的。

Either this or that. 这个或那个。 You code appears to be a strange mix of the two, which is why it doesn't work, and which is why it is impossible to figure out from your original message which approach you were trying to use. 您的代码似乎是两者的奇怪组合,这就是为什么它不起作用的原因,也是为什么无法从原始消息中找出您试图使用哪种方法的原因。

intmax_t should be an integer type that is 32 bits on 32bits compilers and 64bits on 64bit compilers. intmax_t应该是一个整数类型,在32位编译器上为32位,在64位编译器上为64位。 You could use %j in your printf statement to print intmax_t. 您可以在printf语句中使用%j来打印intmax_t。 The size of pointers on one system is always the same - independently of them pointing to int, char or void. 一个系统上的指针大小始终是相同的-与指向int,char或void的指针无关。

printf("%j\n", (intmax_t)array_get(array, 0));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM