The error is clear about the problem. You declare
int SHA1_Init(SHAstate_st*);
As its parameter is declared to be a SHAstate_st*
, is it not compatible with the function pointer declaration which expects the parameter to be a void *
.
You have 2 ways here. The short one is to use reinterpret_cast
. As we know that for any current compiler, a pointer to void or to struct is a mere address, it should work but IMHO it invokes Undefined Behaviour with a strict reading of standard:
newMd->Init=reinterpret_cast<int (*)(void *)(&SHA1_Init); // should work but not really standard compliant
The correct one is to wrap SHA1_Init
.
int SHA1_Init_void(void *p) {
return SHA1_Init(static_cast<SHAstate_st *>(p));
}
You can then correcly use it:
newMd->Init = &SHA1_init_void;
But anyway, you are taking it the wrong way: you are essentialy trying to compile C code in C++ which often leads to many little errors like this one. They are indeed different languages, and have particular semantics on corner cases. And it generally leads to poor code not using all the power of C++ language, mainly type safety guarantee at compile time.
Typically, having pointer to functions taking void *
parameters in a C structure could often be better expressed by method overriding in C++. It will certainly involve more initial work, but IMHO you should considere rewriting the higher level of your code in modern C++ (with classes, constructors, methods and derivation, optionaly templates) and calling lower level C functions. You will get more maintainable code and have a gain in the future. Mixing C and C++ translation units in one single project is perfectly fine, and you just have to enclose the C related include files in extern "C" { ... }
blocks from your C++ source files. The common usage is to put that directly in the .h
files protected with a #ifdef __cplusplus
and is demonstrated in this other SO question: Combining C++ and C - how does #ifdef __cplusplus work?