C 文字int到void*

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

翻译成普通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(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));