不确定如何将C中函数的参数强制转换为void*

不确定如何将C中函数的参数强制转换为void*,c,casting,function-pointers,C,Casting,Function Pointers,我正在编写一个通用哈希表,并创建了一个typedef: typedef unsigned long(*hashFunction_t)(void*,unsigned long); 表示哈希函数的 然后,我在函数add中使用此选项: int add(HashTable *table, hashFunction_t h, void *data); 但是,我从以下行的不兼容指针类型中得到警告初始化: hashFunction_t hash = JenkinsHash; 因为JenkinsHash具

我正在编写一个通用哈希表,并创建了一个typedef:

typedef unsigned long(*hashFunction_t)(void*,unsigned long);
表示哈希函数的

然后,我在函数add中使用此选项:

int add(HashTable *table, hashFunction_t h, void *data);
但是,我从以下行的不兼容指针类型中得到警告初始化:

hashFunction_t hash = JenkinsHash;
因为JenkinsHash具有以下参数:

unsigned long JenkinsHash(const char *str, unsigned long mod);
(void*,unsigned long)
所以我的问题是,我如何转换JenkinsHash以获得参数:

unsigned long JenkinsHash(const char *str, unsigned long mod);
(void*,unsigned long)

谢谢你的帮助

在不调用未定义行为的情况下执行此操作的最佳方法是使用正确的签名创建一个新的thunk函数,为您执行强制转换。开销将是最小的,您可以避免非常不安全的类型转换

unsigned long JenkinsHashThunk(void *str, unsigned long mod)
{
    return JenkinsHash((const char*)str, mod);
}

在不调用未定义行为的情况下执行此操作的最佳方法是使用适当的签名创建一个新的thunk函数来执行强制转换。开销将是最小的,您可以避免非常不安全的类型转换

unsigned long JenkinsHashThunk(void *str, unsigned long mod)
{
    return JenkinsHash((const char*)str, mod);
}

hashFunction\u t hash=hasffunction\u tJenkinsHash?您还可以尝试在typedef:typedef unsigned long*hashFunction\u t;中使用空括号;。只需声明JenkinsHash的第一个参数为void*。您可以在函数的开头将其转换为常量字符*。谢谢@Chnossos的帮助!你这么说似乎很明显。感谢您的帮助。我必须问:未签名的长参数的用途是什么?请不要说这是表的大小,被调用的函数负责执行模运算,而不是由您来执行。只是好奇。为什么散列函数是add函数的一个参数?如果有任何内容,它应该是表本身的属性,请在初始化期间设置。@WhozCraig unsigned long表示表大小。这是一个学校项目,我们得到了JenkinsHash。我不太清楚你这么做是什么意思。为什么JenkinsHash或任何其他哈希函数执行模运算是件坏事?至于设置表的属性,这确实更有意义!我是C语言的新手,这似乎是一种更符合逻辑、更客观的方法,但我不确定是否有一种干净的方法。我现在看到有.hashFunction\u t hash=hassfunction\u tJenkinsHash?您还可以尝试在typedef:typedef unsigned long*hashFunction\u t;中使用空括号;。只需声明JenkinsHash的第一个参数为void*。您可以在函数的开头将其转换为常量字符*。谢谢@Chnossos的帮助!你这么说似乎很明显。感谢您的帮助。我必须问:未签名的长参数的用途是什么?请不要说这是表的大小,被调用的函数负责执行模运算,而不是由您来执行。只是好奇。为什么散列函数是add函数的一个参数?如果有任何内容,它应该是表本身的属性,请在初始化期间设置。@WhozCraig unsigned long表示表大小。这是一个学校项目,我们得到了JenkinsHash。我不太清楚你这么做是什么意思。为什么JenkinsHash或任何其他哈希函数执行模运算是件坏事?至于设置表的属性,这确实更有意义!我是C语言的新手,这似乎是一种更符合逻辑、更客观的方法,但我不确定是否有一种干净的方法。我现在看到,is.void*必须具有与char*相同的表示形式,因此,如果存在这样一种情况,@MattMcNabb就是这样的话,那么这将是不安全类型转换的较小一端。虽然这是一个合理的假设,但并不要求参数的类型对函数指针本身的表示有任何影响。如果实现需要,它们可以存在于完全不同的世界中,就像标准假设函数指针与数据指针不兼容一样,除非实现明确允许。void*必须具有与char*相同的表示形式,因此这将是不安全类型转换规模的较小一端,如果有这样一件事:@MattMcNabb就是这样。虽然这是一个合理的假设,但并不要求参数的类型对函数指针本身的表示有任何影响。如果实现需要,它们可以存在于完全不同的世界中,就像标准假设函数指针与数据指针不兼容一样,除非实现明确允许。