c++ pointers to overloaded functions - c++

I'm trying to expose a overloaded function using boost::python.
the function prototypes are:
#define FMS_lvl2_DLL_API __declspec(dllexport)
void FMS_lvl2_DLL_API write(const char *key, const char* data);
void FMS_lvl2_DLL_API write(string& key, const char* data);
void FMS_lvl2_DLL_API write(int key, const char *data);
I'v seen this answer: How do I specify a pointer to an overloaded function?
doing this:
BOOST_PYTHON_MODULE(python_bridge)
{
class_<FMS_logic::logical_file, boost::noncopyable>("logical_file")
.def("write", static_cast<void (*)(const char *, const char *)>( &FMS_logic::logical_file::write))
;
}
results with the following error:
error C2440: 'static_cast' : cannot convert from 'overloaded-function' to 'void (__cdecl *)(const char *,const char *)'
None of the functions with this name in scope match the target type
trying the following:
void (*f)(const char *, const char *) = &FMS_logic::logical_file::write;
results:
error C2440: 'initializing' : cannot convert from 'overloaded-function' to 'void (__cdecl *)(const char *,const char *)'
None of the functions with this name in scope match the target type
what's wrong and how to fix it?
EDIT
I forgotten to mention a few things:
I'm using vs2010 pro on win-7
write is a member function of logical_file
FMS_logic is a namespace

Well the second attemp should work, if write is a pure function. From your code it seems you do have a memberfunction. Pointers to member-functions are ugly, you'd rather use a function object.
However: you would have to post the whole code, it is not clear whether write is a member-function or not.
Edit: if it is a member-function of FMS_logic::logical_file the syntax would be:
void (FMS_logic::logical_file::*f)(const char *, const char *) = &FMS_logic::logical_file::write;
This just applies for non-static member function, i.e. if a function is static or logical_file is just a namespace it is as you wrote it before.

Your code doesn't work because your function pointer type is wrong. You need to include all type qualifiers (your DLL qualifier is missing) and, as Klemens said, the class name. Putting this together, your code should read
.def("write", static_cast<void FMS_lvl2_DLL_API
(FMS_logic::logical_file::*)(const char *, const char *)>
(&FMS_logic::logical_file::write))
Thanks for the hint with the static_cast<>, I had the same problem as you, just without the dllexport, and after adding the static_cast it works :-)

Related

What is the correct function pointer for an unsigned WINAPI function?

I've a function declared in this way:
unsigned WINAPI searchSTR(void *j);
And I need a pointer to this function. My idea was:
unsigned (*pointerF) (void*);
pointerF = &searchSTR;
But there is an error:
"1 error C2440: '=' : cannot convert from 'unsigned int (__stdcall *)(void *)'
to 'unsigned int (__cdecl *)(void *)' ".
I tried other sintax, but nothing seems correct, he doesn't like the word WINAPI.
Can you suggest me the correct syntax? Maybe it is easy but I am blocked ! Thanks to all
The WINAPI macro expands to __stdcall, which is a different calling convention from the default __cdecl. You need to mark your function pointer with the calling convention to use:
unsigned (WINAPI *pointerF) (void*)
auto pointerF = &searchSTR;
Stop writing 1990's code. The compiler already knows the right type.

use external function as member-function pointer

Is it possible in C++ to create a function which is not defined in class A but can be treated like a method pointer? Eg.:
typedef bool (A::*MethodType)(int a);
MethodType g_someMethod = &A::SomeMethod;
Now, I want to create a new function AnotherMethod which is of the type MethodType. I have tried to do the following:
bool A_AnotherMethod(A* _this, int a) {
std::cout << __FUNCTION__ << "\n";
return true;
}
MethodType g_someMethod = A_AnotherMethod;
// ...
(this->*g_someMethod )(42);
But I get
error C2440: '=' : cannot convert from 'bool (__cdecl *)(A *,int)' to 'bool (__cdecl A::* )(int)'
How to do it correctly?
No, you can't. C++ does not have a feature similar to extension methods in C#.
p.s. Method pointers have clumsy syntax in C++ and are rarely used. But this is the way how they are defined in the language.

build error: none of the 12 overloads could convert all the argument types

I use an overload function that is defined as follows in one of my header files
// indexed variables: todo overloads
extern int PmdgGetVariable(char *variableName, int index, bool* result);
extern int PmdgGetVariable(char *variableName, int index, short* result);
extern int PmdgGetVariable(char *variableName, int index, unsigned short* result);
extern int PmdgGetVariable(char *variableName, int index, int* result);
extern int PmdgGetVariable(char *variableName, int index, unsigned int* result);
extern int PmdgGetVariable(char *variableName, int index, float* result);
I get an error from the build prosess when
trying these arguments
int res = PmdgGetVariable("MCP", 0, 0);
error is
main.cpp(80): error C2665: 'PmdgGetVariable' : none of the 12 overloads could convert all the argument types
1> c:\users\roar\documents\visual studio 2010\projects\iocpclient_ngx v0.3\PmdgSiocConnector.h(27): could be 'int PmdgGetVariable(char *,int,bool *)'
1> c:\users\roar\documents\visual studio 2010\projects\iocpclient_ngx v0.3\PmdgSiocConnector.h(28): or 'int PmdgGetVariable(char *,int,short *)'
1> c:\users\roar\documents\visual studio 2010\projects\iocpclient_ngx v0.3\PmdgSiocConnector.h(29): or 'int PmdgGetVariable(char *,int,unsigned short *)'
1> c:\users\roar\documents\visual studio 2010\projects\iocpclient_ngx v0.3\PmdgSiocConnector.h(30): or 'int PmdgGetVariable(char *,int,int *)'
1> c:\users\roar\documents\visual studio 2010\projects\iocpclient_ngx v0.3\PmdgSiocConnector.h(31): or 'int PmdgGetVariable(char *,int,unsigned int *)'
1> c:\users\roar\documents\visual studio 2010\projects\iocpclient_ngx v0.3\PmdgSiocConnector.h(32): or 'int PmdgGetVariable(char *,int,float *)'
1> while trying to match the argument list '(const char [4], int, int)'
I am new to C++ and overloads. What am I doing wrong? What should/can I have as the 3rd argument?
rgs
There are two issues here.
"MCP" has type char const[4] which decays into char const*. This is not compatible with the first argument char*. Maybe you need to fix those function signatures to take char const* arguments?
If the functions are not yours and are correct (i.e., they actually need to change the first argument), then you need to pass an argument that is mutable:
char mcp[] = "MCP"; // now this properly decays to char*
int res = PmdgGetVariable(mcp, 0, 0); // beware of buffer overflow issues
If the function signatures are not correct because they don't change the first argument, despite taking a non-const parameter, you can resort to const_cast.
The other problem is that 0 can be converted to all those pointer types. There is no way for the compiler to decide which one of those functions to pick. You need to either be explicit about the type with a cast, or use a variable with the proper type.
PmdgGetVariable(mcp, 0, static_cast<int*>(0));
I find it strange that the function can be called with a null pointer and has all those overloads. Maybe it requires a non-null pointer?
int x = 0;
int res = PmdgGetVariable(mcp, 0, &x);
The problem is with the first parameter. Character literals ("MCP" in your example) are of type const char* and there is no overload that has const char* as its first argument.
I'd say it is because your call is ambiguous. Since you are passing a nullptr as your third parameter without type information, any of the overloads shown could potentially be correct.
To fix, try something like:
bool fParam = true;
int res = PmdgGetVariable("MCP", 0, &fParam );
All your overloads have a pointer as the third parameter & so, if you don't pass a pointer, the compiler will generate an error.
What are you doing wrong - don't know. What is this function supposed to do? Is it supposed to return a result into a caller var passed by reference? I'm guessing so because the third param. is names 'result', so:
bool myResult;
..
int res = PmdgGetVariable("MCP", 0, &myResult);
..or any of the other 5 overloaded result types.
Because when you write:
PmdgGetVariable("MCP", 0, 0);
Just looking at this line and knowing there are many possible such functions, how do you know if you're referring to the PmdgGetVariable with the third parameter bool*? short*? int*?. When you specify the literal '0', that literal could be referring to any of those types

strrchr causing 'Cannot convert from const char * to char *'

I am trying to compile some code that was given to me that I'm told compiles fine. Perhaps on a different compiler. I am using VS2010 and I have the following line:
char *dot = strrchr(filename, '.');
This causes the compiler error:
"error C2440: 'initializing': cannot convert from 'const char *' to
'char *'
How come? And how do I fix it?
The error message is pretty clear. strrchr returns a const char*. So you need:
const char *dot = strrchr(filename, '.');
If you really need a char*, you can use strcpy for conversion.
C++ has saner versions of strchr and strrchr than C thanks to overloading, so say:
const char * dot = strrchr(filename, '.');
In C, which has no overloading, you only have a single function char * strrchar(const char *, const char *), and it's up to you to decide whether the result is constant or mutable, depending on which type of pointer to feed into the function. C has many such type-unsafe functions.

_begintheadex function call problem

I have a class SoundManager which contains a function called 'recordLoop'. In the constructor of the SoundManager, I am using this code:
recordHandle = (HANDLE)_beginthreadex(NULL,0,recordLoop,
(void*)exinfo->length,CREATE_SUSPENDED,0);
It is giving me the following errors:
error C3867: 'SoundManager::recordLoop': function call missing argument list; use '&SoundManager::recordLoop' to create a pointer to member
IntelliSense: argument of type "unsigned int (__stdcall SoundManager::*)(void *params)" is incompatible with parameter of type "unsigned int (__stdcall *)(void *)"
So I've tried using the &SoundManager::recordLoop as suggested, but it gives me this:
error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned int (__stdcall SoundManager::* )(void *)' to 'unsigned int (__stdcall *)(void *)'
IntelliSense: argument of type "unsigned int (__stdcall SoundManager::*)(void *params)" is incompatible with parameter of type "unsigned int (__stdcall *)(void *)"
Is it illegal to start a thread on a class method or did I do something wrong?
Thanks in advance
EDIT: Sorry forgot to add the recordLoop >.< here it is:
public:
unsigned __stdcall recordLoop(void* params);
It's illegal to start a thread on a non-static class member since there is no way for the created thread to know what this is.
What is the definition of recordLoop?
I had the same problem with casting.
Ignoring all other problems like one mentioned in the answer above, function pointer must be cast to (unsigned(__stdcall*)(void*)) in _beginthreadex, no matter what type the function is or what is its parameter list.