Doing what you describe is generally considered to be a Bad Idea. The more the compiler can help you by type-checking, the fewer bugs you'll have to find yourself, the hard way.
That said, it isn't really easy to write polymorphic functions in C, so I can sympathize. However, there are ways around it.
If your function always takes some kind of integer, one thing you can do is type the argument as uintptr_t (defined in C99... you might have to include stdint.h, or write your own -- I forget). It is the same size as a pointer on any architecture (e.g. -- it is 32-bits on x86 and 64-bits on x64). If you need signed integers, use intptr_t. If you don't want to cast all the time when calling the function, you can write a bunch of "front-ends" to it that each take the appropriate type and do the cast for you (this is what I do in my kernel).
You could also use macros, but you could also always gouge out your eyes with a butter knife. I'm not sure why you'd want to.
You could switch to C++ and use templates -- that's what they were invented for.
If your function is supposed to take a lot of different types that are a lot different from each other, you could always use a "discriminated union" -- that's a struct with two fields -- a union, and a type indicator that tells you what field of the union is valid.
There is actually a C API in common use today that does what you describe --
ODBC. Those of us who live and breathe it every day wish that it didn't abuse void* the way it does.