代码之家  ›  专栏  ›  技术社区  ›  Nathan F.

检查函数是否与C中的my typedef函数类型相同?

  •  1
  • Nathan F.  · 技术社区  · 7 年前

    我有以下代码:

    typedef int state_requester(void* request_paramaters);
    
    int doSomething(state_requester* requester) {
    
        // This if statement is what I'm trying to
        // figure out how to do.
    
        if (requester isoftype state_requester) {
            requester(NULL);
            return 1;
        } 
    
        return 0;
    }
    

    我正试图找到一种方法来验证 传递的参数实际上是有效的 state_requester 函数格式,然后再尝试执行它。

    if ( x isoftype y ) 关于函数typedefs。

    2 回复  |  直到 7 年前
        1
  •  1
  •   gsamaras a Data Head    7 年前

    在C中不能这样做。

    类型是在编译时检查的,而不是在运行时。

    注: requester is类型 state_requester* ,而不是 state_requester

        2
  •  0
  •   Nathan F.    7 年前

    虽然没有真正的方法直接验证数据是否属于特定类型,但我已经找到了一种“假设”该类型匹配的方法。

    这并不能百分之百保证它是指定的类型。然而,它将假定它基于类型代码。

    我还添加了一些测试。我在几分钟内写下了这篇文章,所以我确信它还有改进的空间,我决不是一个本地开发人员。我只是有一个需要,写了它。如果这对某人有帮助,那太棒了!

    #include <stdio.h>
    #include <stdlib.h>
    
    
    // Type Definitions
    
    // These are the type definitions that can be used to check for type
    // They need to be unique so that only types starting with these
    // prefixes will be presumed to be of the type specified.
    typedef enum type {
        TYPE_StateRequester = 0x10f3ccd3,
        TYPE_OtherThing = 0x09331c8c
    } type;
    
    
    // State Requester Definitions & Functions
    
    typedef int state_requester_f(void* request_parameters);
    
    // Since we want to check the "type" of a function reference,
    // we need to wrap it in a struct along with it's type code.
    struct state_requester_t {
        int type;
        state_requester_f* call;
    } typedef state_requester_t;
    
    state_requester_t new_state_requester(state_requester_f* call) {
        state_requester_t sr;
        sr.type = TYPE_StateRequester;
        sr.call = call;
        return sr;
    }
    
    // This function will check if data is of type StateRequester
    // 
    // If the data sent to this function is not of the length
    // nessecary for the state_requester type, - OR - 
    // it's type property is not equal to the StateRequester type
    // then we will presume that this data is NOT of type StateRequester
    uint8_t is_state_requester(void* data, size_t len) {
        return len == sizeof(state_requester_t) && 
               ((state_requester_t*)data)->type == TYPE_StateRequester;
    }
    
    
    // Testing functions
    
    int test_caller(void* data) {
        printf("Got to the test_caller function.\n");
    
        return 0;
    }
    
    int main(int agc, char *argv[]) {
    
        // Create an actual state_requester_t definitiion
        state_requester_t sr = new_state_requester(&test_caller);
    
        // Test to see if it's validated as a state_requester_t
        if (is_state_requester(&sr, sizeof(state_requester_t))) {
            printf("Yes, variable 'sr' is presumadely of type state_requester_t\n");
            sr.call(NULL);
        } else {
            printf("No, variable 'sr' is not of type state_requester_t\n");
        }
    
        // Create a phony state_requester_t definition,
        // but keep it the same length as a regular
        // state_requester_t
        void* a = malloc(sizeof(state_requester_t));
    
        // Test to see if it's validated as a state_requester_t
        if (is_state_requester(a, sizeof(state_requester_t))) {
            printf("Yes, variable 'a' is presumadely of type state_requester_t\n");
        } else {
            printf("No, variable 'a' is not of type state_requester_t\n");
        }
    
        free(a);
    
        // Create a phony state_requester_t with an improper length
        void* b = malloc(5);
    
        // Test to see if it's validated as a state_requester_t 
        if (is_state_requester(b, sizeof(state_requester_t))) {
            printf("Yes, variable 'b' is presumadely of type state_requester_t\n");
        } else {
            printf("No, variable 'b' is not of type state_requester_t\n");
        }    
    
        free(b);
    
        return 0;
    }