0

GPOINTER_TO_INTと GINT_TO_POINTERをプレーンな CI に変換すると、次のようになります。

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

ポータブルですか?

なぜにキャストするのlongですか?

GTK ではコールバックに使用されます。

#define FLAG 10

static void panel_set_handler(GtkWidget *widget, gpointer data)
{
    panel_set(GPOINTER_TO_INT(data));
}

g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(panel_set_handler), GINT_TO_POINTER(FLAG));
4

1 に答える 1

2

解決策 1: キャスト

最も単純な、 との間でキャストするだけintptr_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;
}

intsで使用するラッパーを次に示します。

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

その方法は、これらすべてのキャストを除いた投稿に少し似ています。

于 2013-06-27T12:26:39.970 に答える