如何将两个数组传递给一个参数中的函数?

时间:2011-11-23 00:18:26

标签: c callback

我有这段代码:

unsigned short (*pixel_array)[SCREEN_HEIGHT] = get_ok_zone(mouse_mask); 
unsigned short (*pixel_border)[2] = get_ok_zone_border(pixel_array); 

让我可以访问这两个数据数组。

我需要以某种方式将这两个数组作为ONE参数传递给函数。

我不仅无法弄清楚如何传递它们,我无法弄清楚一旦我将它们放入函数中后如何单独访问它们。

我一整天都在努力去理解这一点,它似乎正在逃避我。

有人可以向我解释一下我需要做什么才能将这两个数组通过一个参数(可能在一个指针数组中)传递给一个函数,以及如何在函数内部访问它们?

编辑:我将参数(我唯一可以通过的参数)传递给Quartz Event Tap callback.

编辑2: @Kevin

我创建了结构:

struct array_stack {
    unsigned short (*pixel_array)[SCREEN_HEIGHT]; 
    unsigned short (*pixel_border)[2]; 
};

然后,在我的int main()中,我有:

struct array_stack as = {get_ok_zone(mouse_mask), get_ok_zone_border(get_ok_zone(mouse_mask))};



CFRunLoopSourceRef runLoopSource;
CGEventMask event_mask;
event_mask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventOtherMouseDragged);

CGSetLocalEventsSuppressionInterval(0);

CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, as);

(我将as作为代码块底部CGEventTapCreate()的最后一个参数传递;

我收到错误passing struct array_stack to a parameter of incompatible type 'void',错误指向我:

CG_EXTERN CFMachPortRef CGEventTapCreate(CGEventTapLocation tap,
CGEventTapPlacement place, CGEventTapOptions options,
CGEventMask eventsOfInterest, CGEventTapCallBack callback,
void *userInfo) CG_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);

void *userInfo是接收我的参数的参数,最终会传递给回调函数。

4 个答案:

答案 0 :(得分:7)

将它们包裹在struct

struct wrapper {
    unsigned short (*arr)[SCREEN_HEIGHT];
    unsigned short (*border)[2];
}

这是一个常见的技巧,特别是对于回调。您可以通过将指针传递给存储了所有内容的结构来使用它来通过void *传递任何内容。

答案 1 :(得分:2)

扩展Kevin's answer,执行此操作的方法是使用指向结构的指针。但是,您必须要小心对象的生命周期:只要可以访问数据,结构就必须继续保持有效。

如果可以保证访问数据的生命周期,可以使用堆栈变量或全局变量:

typedef struct pixel_data
{
    unsigned short (*pixel_array)[SCREEN_HEIGHT];
    unsigned short (*pixel_border)[2];
} pixel_data;

...

pixel_data data = {get_ok_zone(mouse_mask), get_ok_zone_border(pixel_array)};
CGEventTapCreate(..., &mouse_filter, &data);
// 'data' must remain alive for as long as mouse_filter might get called

...

CGEventRef mouse_filter(..., void *refcon)
{
    pixel_data *data = refcon;  // implicit cast
    // do stuff with data->pixel_array and data->pixel_border
}

如果您在任何给定时间只有一个回调活动,您可以使用全局对象(在这种情况下,您实际上甚至不需要通过void*参数传递数据 - 您可以从回调中访问全局数据。)

更有可能的是,如果您在飞行中有多个可能有不同数据的回调,唯一安全的做法是在创建时malloc每个回调数据,完成后free

pixel_data *data = malloc(sizeof(pixel_data));
data->pixel_array = ...;
data->pixel_border = ...;
CGEventTapCreate(..., &mouse_filter, data);
...
// When the event is deleted/done/whatever:
free(data);  // The callback mouse_filter should never be called after this
             // with this data

答案 2 :(得分:1)

你就是这样做的。

代码:

#include <stdio.h>
#define SCREEN_HEIGHT 2

struct container {
unsigned short (*pixel_array)[SCREEN_HEIGHT]; 
unsigned short (*pixel_border)[2]; 
};

void function(struct container );

int main (){
struct container container1;

container1.pixel_array = (int *) malloc (2*sizeof(int *));
container1.pixel_border = (int *) malloc (2*sizeof(int *));
(*container1.pixel_array)[0] = 88;
(*container1.pixel_array)[1] = 99;
(*container1.pixel_border)[0] = 77;
(*container1.pixel_border)[1] = 66;

function(container1);

return 0;}

void function(struct container x) {
printf("container1.pixel_array[0] = %d\n",(*x.pixel_array)[0]);
printf("container1.pixel_array[1] = %d\n",(*x.pixel_array)[1]);
printf("container1.pixel_border[0] = %d\n",(*x.pixel_border)[0]);
printf("container1.pixel_border[1] = %d\n",(*x.pixel_border)[1]);
}

输出:

container1.pixel_array[0] = 88
container1.pixel_array[1] = 99
container1.pixel_border[0] = 77
container1.pixel_border[1] = 66

但是,我收到2条警告,有人可以帮忙指出如何更正警告吗?

警告:

struct_2array.c:19: warning: assignment from incompatible pointer type
struct_2array.c:20: warning: assignment from incompatible pointer type

container1.pixel_array = (int *) malloc (2*sizeof(int *));
container1.pixel_border = (int *) malloc (2*sizeof(int *));

更新: 为了适应以void *为参数的OP功能,我稍微更改了代码,但是,我仍然收到malloc行的警告:

#include <stdio.h>
#define SCREEN_HEIGHT 2

struct container {
unsigned short (*pixel_array)[SCREEN_HEIGHT]; 
unsigned short (*pixel_border)[2]; 
};

void function(void *);

int main (){
struct container container1;

container1.pixel_array = malloc (2*sizeof(int *));
container1.pixel_border =  malloc (2*sizeof(int *));
(*container1.pixel_array)[0] = 88;
(*container1.pixel_array)[1] = 99;
(*container1.pixel_border)[0] = 77;
(*container1.pixel_border)[1] = 66;

function(&container1);

return 0;}

void function(void *x) {
struct container container2 = *(struct container *)x;
printf("container1.pixel_array[0] = %d\n",(*container2.pixel_array)[0]);
printf("container1.pixel_array[1] = %d\n",(*container2.pixel_array)[1]);
printf("container1.pixel_border[0] = %d\n",(*container2.pixel_border)[0]);
printf("container1.pixel_border[1] = %d\n",(*container2.pixel_border)[1]);
}

答案 3 :(得分:0)

使用struct,这可能是最简单的。

union void*如果您想通过。