如何让用户将点击处理程序功能绑定到按钮?

问题描述

我目前正在使用SDL2库为我用C( c89 )编写的程序构建自己的GUI。

问题

我想让我的代码用户通过自己的点击处理程序函数,每次在相应按钮的表面上触发click事件时都会调用函数

我尝试过的

我认为我可以像这样使用功能指针

bind_ClickHandler(void (*function)(void)) {/* bind it to a button */}

但是,显然,这对于用户来说太过局限了。

所以我尝试使用 stdarg.h

/* ... : arguments to pass to the click handler */
bind_ClickHandler(void (*function)(),int nb_args,...) 
{ 
     void *arg_pt;
     va_list args;
     va_start(args,nb_args);
     /* I don't kNow what to do so i cast it as a garbage pointer */
     arg_pt = va_arg(args,void *);
     
     /* repeat this in a loop to save the args and bind the click handler to a button */ 
}

使用此代码,我可以将参数传递给点击处理程序,但前提是我知道它们的类型

我想要什么

我想使用类似第二段代码方法,我向您展示了如何将args保存以传递给click处理程序,但是它不起作用,因为我需要知道使用 va_arg的args的类型。 ()

解决方法

只需传递单个const [files,setFiles] = useState(null); const handleFileUpload = e => { setFiles(e.target.files[0]); setTimeout(() => { console.log(files); },5000); }指针。像qsort_rpthread_create [*]。用户只需要一个指针-该指针将指向用户想要的任何地方。

df <- data.frame(ID = seq(1,8),fruit = c("apple","orange","kiwi","pear","apple","apple"),stringsAsFactors = F)

# Create Column to store true false values
df$previous_n <- FALSE

# Define Variable for how far to look back
n <- 3

# Loop through each row of dataframe df
for (i in seq_len(nrow(df))) {
  # Only calculate for the second row on
  if (i > 1) {
    # Find the starting index for the previous values
    start_value <- ifelse(i - n < 1,1,i - n)
    # Identify the current value in the row
    c_value <- df$fruit[i]
    
    # Identify all previous values
    previous_values <- df$fruit[start_value:i - 1]
    # Check if the current value is in list of previous values,and add result to df
    df$previous_n[i] <- c_value %in% previous_values
  }
}

df
 ID  fruit previous_n
1  1  apple      FALSE
2  2 orange      FALSE
3  3   kiwi      FALSE
4  4   pear      FALSE
5  5 orange       TRUE
6  6   kiwi       TRUE
7  7  apple      FALSE
8  8  apple       TRUE

一个指针就足够了:

void*

[*]-或thrd_createfopencookie使用void (*clickhandler_user_function)(void *) = NULL; void *clickhandler_user_function_arg = NULL; void bind_ClickHandler(void (*function)(void*arg),void *function_arg) { // store function and fucntion_arg somewhere clickhandler_user_function = function; clickhandler_user_function_arg = function_arg; } 或标准sigevent使用struct user_context_s { int some_number; const char *some string; // etc. }; void user_function_that_operates_on_user_context(void *p) { struct user_context_s *ctx = p; printf("My number is: %d\n",ctx->some_number); } int main() { // user can use malloc() and manage the lifetime of it's context struct user_context_s ctx = {1,"blabla"}; bind_ClickHandler(user_function_that_operates_on_user_context,&user_context); } 中的void *cookie在{ {1}}。