I am trying to convert a C code to C++. In my .c file I've definitions like this:
void services(void);
void transfers(void);
Further more, a thread will initialize the above two like this:
_beginthread((void*) services,0,NULL);
_beginthread((void*) transfers,0,NULL);
When I try to compile, I got the following error at both the places above like this:
Conversion from void* to pointer to non-void required an Explicit cast: Cannot convert parameter 1 from void* to void(_cdecl*)(void*)
I am confused about this, hope you guys make it clear for me :-)
The solution is to use functions of the correct type and not cast them. Ignore the parameter if it's not relevant to the code.
void services(void*);
void transfers(void*);
_beginthread(services, 0, NULL);
_beginthread(transfers, 0, NULL);
If you absolutely can't change the functions, e.g. if you don't have access to the sources, use wrappers:
void correct_services(void*) { services(); }
_beginthread(correct_services, 0, NULL);
The compiler is helping you here - don't try to work around it by lying to it.
It looks like you are trying to convert from C++ calling standard to C calling standard. cdecl stands for C declaration.
To manually define a function to be cdecl you can use void _cdecl funct();
Try:
_beginthread((void(_cdecl*)(void*)) services, 0, NULL);
What you were doing was explicitly casting the function pointer to a non-function pointer type (void *). This was OK. But the _beginthread function expects as its first parameter a function pointer of the correct type mentioned in the error message. So you need to fix your cast.
If you're about to downvote this answer, I'd appreciate to know the reason why. I know it would be much better if user2754070 wanted to change the prototype of services (see my comments below). However, what I'm suggesting works (the answer was accepted) and, as far as I know, it is safe and standard practice in C libraries spawning threads. If you think it's not, please explain why and I'll consider deleting the answer.
Related
I saw this line of code in a source code and I simply can't understand what its meaning is even after having searched around (I don't know what exactly to search for). Can someone explain what this is for or where I can read up on it?
using f_loadLibraryA = HINSTANCE(WINAPI*)(const char* lpLibFilename);
Sorry for such a dumb question...
f_loadLibraryA becomes a type (almost like a typedef) for a function that takes a const char* as its single parameter and has a return type of HINSTANCE.
WINAPI is a #define macro that maps to a calling convention, which is not part of the C++ standard, but exists to establish how the function should be called (how parameters are loaded onto the call stack, and other low level things like that). It's usually either __stdcall or __cdecl.
It declares f_loadLibraryA to be a type alias for HINSTANCE(WINAPI*)(const char* lpLibFilename).
See also: https://en.cppreference.com/w/cpp/language/type_alias
I have an old C++ code that has this line of code:
int logprintf( const char* ptr, ... );
and I am not sure what does it do exactly? should I change the code in order to be able to compile the code with new versions of the compiler?! does anybody have an idea? any help would be appreciated.
That's just C code and any compiler made since the 1980s should be able to handle it. The definition is of a varidic function, or "varargs" in C parlance.
What that does is declare a method signature, nothing more. Presumably somewhere else, either in a library you link in or in a C or C++ file you compile there's a matching implementation.
Most printf-style functions do not have a fixed number of arguments. This is what the ellipsis ... represents, zero or more arbitrary arguments go there.
I'm working on creating a user-level thread library and what I want to do is run a function inside a stub and so I would like to pass the function pointer to the stub function.
Here is my stub function:
void _ut_function_stub(void (*f)(void), int id)
{
(*f)();
DeleteThread(id);
}
This is what the user calls. What I want to do is get pointer of _ut_function_stub to assign to pc and I've tried various different options including casting but the compiler keeps saying "invalid use of void expression".
int CreateThread (void (*f) (void), int weight)
{
... more code
pc = (address_t)(_ut_function_stub(f, tcb->id));
... more code
}
Any help is appreciated. Thanks!
If you're interested in implementing your own user-level-threads library, I'd suggest looking into the (now deprecated) ucontext implementation. Specifically, looking at the definitions for the structs used in ucontext.h will help you see all the stuff you actually need to capture to get a valid snapshot of the thread state.
What you're really trying to capture with the erroneous (address_t) cast in your example is the current continuation. Unfortunately, C doesn't support first-class continuations, so you're going to be stuck doing something much more low-level, like swapping stacks and dumping registers (hence why I pointed you to ucontext as a reference—it's going to be kind of complicated if you really want to get this right).
I am exploring the possibility of creating a Clutter binding for the D
language ( http://d-programming-language.org/) and have started by
trying some simple tests using dynamic loading of libclutter. I've run
into a problem that might derive from the GObject inheritance
system, and I'd appreciate any help getting it figured out. Here's the
rundown: using clutter_stage_get_default returns a ClutterActor* which
I can use with the clutter_actor_* methods. But I always get errors or
segfaults when I use the clutter_stage_* or clutter_container_*
methods. Here's my test code: http://pastebin.com/nVrQ69dU
At the clutter_container_add_actor call on line 56, I get the following error:
(<unknown>:11976): Clutter-CRITICAL **: clutter_container_add_actor:
assertion 'CLUTTER_IS_CONTAINER (container)' failed
In example code, I have noticed the CLUTTER_STAGE and
CLUTTER_CONTAINER macros for casting (these obviously are not
available to me), but as far as I could tell, they simply performed
some checks, then did a plain C cast. If this is incorrect, and some
Gobject type magic needs to be done on the stage pointer before
casting, please let me know. Binding and using the
clutter_stage_set_title or clutter_stage_set_color with cast(ClutterStage*)stage resulted in
segmentation faults, presumably the same issue.
EDIT: Here's a stripped down example with no external dependencies (if you're not on Linux, you'll need to replace the dl calls with your OS's equivalents). This code fails with a segfault, which according to GDB and Valgrind, is in clutter_stage_set_title (in /usr/lib/libclutter-glx-1.0.so.0.600.14)
The problem is that you don't declare the C functions as extern(C). Because of that dmd thinks you're calling a D function and uses the wrong calling convention. One way to do this correctly is like this:
alias extern(C) void function(void*, const char*) setTitleFunc;
auto clutter_stage_set_title = getSym!(setTitleFunc)("clutter_stage_set_title");
I'm not sure how to make it work without the alias though. DMD refuses to parse anything with extern(C) in a template parameter:
auto clutter_stage_set_title = getSym!(extern(C) void function(void*, const char*))("clutter_stage_set_title"); //Doesn't work
BTW: Your cstring function is dangerous: It returns a char* indicating that the string can be modified, but this is not always true: If you pass a string literal to toStringz it might not allocate new memory but return the pointer of the original string instead. String literals are in readonly memory, so this could lead to problems.
You could just adjust your function types to match the C Types (const gchar* in C --> const char* in D) and use toStringz directly.
structs in D cannot inherit from each other and casting struct pointers will return null unless there's a intermediate cast to void* (unlike a C cast) I got refuted here
you're better off adding another abstraction layer using handle-wrapping structs and emulating the checks from those macros when casting
but what happens if you do
clutter_container_add_actor(cast(ClutterContainer*)(cast(void*)stage), textbox);
(casting to void* first and then to ClutterContainer*)
All,
I am writing a small c++ app and have been stumped by this issue. Is there a way to create (and later catch ) the error while accessing element from va_list macro using va_arg if element type is not expected. Eg:-
count=va_arg(argp,int);
if (count <= 0 || count > 30)
{
reportParamError(); return;
}
Now, if I am passing a typedef instead of int, I get garbage value on MS compiler but 95% of time count gets value 0 on gcc (on 64 bit sles10 sys). Is there a way I can enforce some typechecking, so that I get an error that can be caught in a catch block?
Any ideas on this would be very helpful to me. Or is there a better way to do this. The function prototype is:-
void process(App_Context * pActx, ...)
The function is called as
process(pAtctx,3,type1,type2,type3);
It is essential for pActx to be passed as 1st parameter and hence cannot pass count as 1st parameter.
Update-1
Ok, this sounds strange but nargs does not seem to part of va_list on sles10 gcc. I had to put in
#ifdef _WIN32
tempCount=va_arg(argp,int)
#endif
After using this, parameters following nargs do not get garbage values. However, this introduces compiler/platform based #ifdefs....Thanks Chris and Kristopher
If you know a count will always be passed as the second argument, then you could always change the signature to this:
void process(App_Context * pActx, int count, ...)
If that's not an option, then there is really no way to catch it. That's just how the variable-argument-list stuff works: there is no way for the callee to know what arguments are being passed, other than whatever information the caller passes.
If you look into how the va_arg macro and related macros are implemented, you may be able to figure out how to inspect all the stuff on the stack. However, this would not be portable, and it is not recommended except as a debugging aid.
You also might want to look into alternatives to variable-arguments, like function overloading, templates, or passing a vector or list of arguments.
No, there is no way. varargs doesn't provide any way to check the types of parameters passed in. You must only read them with the correct type which means that you need another way of communicating type information.
You are likely to be better off avoiding varargs functionality unless you really need it. It's only really a C++ feature for the sake of legacy functions such as printf and friends.