C 文字int到void*
翻译成普通C我得到:C 文字int到void*,c,casting,void-pointers,C,Casting,Void Pointers,翻译成普通C我得到: #include <stdio.h> #include <stdlib.h> void *fn(void *v) { int *i; i = malloc(sizeof(int)); *i = (int)(long)v; return i; } int main(void) { int *i = fn((void *)(long)10); printf("%d\n", *i); free
#include <stdio.h>
#include <stdlib.h>
void *fn(void *v)
{
int *i;
i = malloc(sizeof(int));
*i = (int)(long)v;
return i;
}
int main(void)
{
int *i = fn((void *)(long)10);
printf("%d\n", *i);
free(i);
return 0;
}
解决方案1:强制转换
最简单的方法是在intptr\u t
之间进行转换。这是GLib宏的正确版本
解决方案2:使用堆
如果您有比intptr\t更大的内容,或者当您对大小没有信心时,您可以使用动态分配的内存指针,这次无需强制转换:
void* ToHeap(void const *data, size_t dataSize)
{
void* ret = malloc(dataSize);
if(ret != NULL)
memcpy(ret, data, dataSize);
return ret;
}
int FromHeap(void* heapPtr, void *data, size_t dataSize)
{
int ret = 0;
if(heapPtr != NULL)
{
memcpy(data, heapPtr, dataSize);
free(heapPtr);
ret = 1;
}
return ret;
}
下面是一个用于int
s的包装器:
void* IntToHeap(int i)
{
return ToHeap(&i, sizeof(int));
}
int IntFromHeap(void*heapPtr, int defaultValue)
{
int ret;
if(!FromHeap(heapPtr, &ret, sizeof(int))
ret = defaultValue;
return ret;
}
您可以这样使用:
#define FLAG 10
static void panel_set_handler(GtkWidget *widget, gpointer data)
{
panel_set(IntFromHeap(data, 0));
}
g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(panel_set_handler), IntToHeap(FLAG));
这种方式有点像你的帖子,没有这些类型转换。这篇文章的每一个方面都很糟糕。你到底想达到什么目的?如果有的话,您可以在
uintpr\u t
或intptr\u t
中存储一个空指针。intptr\u t()更好为什么强制转换为long?你不需要它。我的问题是你为什么要做那样的事?@KerrekSB我知道这很糟糕,我正在努力理解,明白吗edit@Armin,glib的家伙们正在施放,你可以在这里看到,为什么?+1,但我不想有其他选择,我想知道这段代码是否可移植,以及使用(long)施放(int)(long)的原因,我想说它不可移植。在LLP64模型下,指针比长指针大。我也不明白为什么fn
会采用单向(强制转换)参数并通过动态分配返回它。谢谢Medinoc,在这种情况下没有理由,在GTK中,原因是通过回调获取参数并将结果设置为void*
。我编辑了我的帖子,以供您真正想要/需要使用堆的情况下使用。但是这次没有强制转换(因此,您要么使用堆,要么使用强制转换)。
#define FLAG 10
static void panel_set_handler(GtkWidget *widget, gpointer data)
{
panel_set(IntFromHeap(data, 0));
}
g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(panel_set_handler), IntToHeap(FLAG));