I want to to be able to have my typedef function inside a class. But i dont find a way to do that. I need to scan for the address so i cant hardcode it in, therfor i need to sett the address like this SetCursorPosFunction = (_SetCursorPos)(address to function);
example:
class Cursor
{
public:
typedef BOOL(__stdcall *_SetCursorPos) (int X, int Y);
_SetCursorPos SetCursorPosFunction;
};
I want to be able to call the function like this Cursor::SetCursorPosFunction(x,y)
Example of what i mean.
void Function()
{
DWORD_PTR AddressToFunctionSetCourserPos = Find(....);
Cursor::SetCursorPosFunction = (Cursor::_SetCursorPos)(AddressToFunctionSetCourserPos ); //In final version it is going to be in a separate function where i get all the functions i need (This find() function can not be looped or called often, it is going to create lag etc.).
Cursor::SetCursorPosFunction(1, 1);
}
I get the errors:
fatal error LNK1120: 1 unresolved externals
error LNK2001: unresolved external symbol "public: static int (__cdecl* Cursor::SetCursorPosFunction)(int,int)" (?SetCursorPosFunction#Cursor##2P6AHHH#ZEA)
Modifying the function to a static will allow you to use it without have to instantiate a member first as you like:
class Cursor
{
public:
typedef BOOL(__stdcall *_SetCursorPos) (int X, int Y);
static _SetCursorPos SetCursorPosFunction;
};
Cursor::SetCursorPosFunction(x,y) should now work (given you initialize it first).
You also need to initialize the static member in global space. Something like Cursor::_SetCursorPos Cursor::SetCursorPosFunction = nullptr; should work. But be careful to have it in only one translation unit.
If you intended to emulate a member function you should create an instance of the cursor before trying to use it:
Cursor cursor;
cursor.SetCursorPosFunction(x, y);
You can also add a constructor to your class to initialize the pointer:
class Cursor
{
public:
Cursor()
: SetCursorPosFunction((_SetCursorPos) GetProcAddress(...))
{ }
typedef BOOL(__stdcall *_SetCursorPos) (int X, int Y);
const _SetCursorPos SetCursorPosFunction;
};
Related
I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class in C++ but I'm getting compilation errors.
The API definition is:
typedef void (__stdcall *STREAM_CALLBACK)(void *userdata);
__declspec(dllimport) int __stdcall set_stream_callback(
STREAM_CALLBACK streamCB, void *userdata);
One example file, provided by the third party, is:
void __stdcall streamCB(void *userdata)
{
// callback implementation
}
int main(int argc, const char argv[])
{
int mid = 0;
set_stream_callback(streamCB, &mid);
}
And that works fine.
However when I try to use that in a class, I have an error:
error C3867: 'MyClass::streamCB': function call missing argument list;
use '&MyClass::streamCB' to create a pointer to member
The suggestion to use
&MyClass::streamCB
doesn't work.
I understood that the set_stream_callback only accepts a non-member function.
The problem is very similar to
How can I pass a class member function as a callback?
in which Johannes makes a concise suggestion, however I do not understand it very well. Could anyone expand a bit, if I am correct that it is relevant to this question?
I have tried:
void __stdcall MyClass::streamCB(void *userdata)
{
// callback implementation
}
static void MyClass::Callback( void * other_arg, void * this_pointer ) {
MyClass * self = static_cast<ri::IsiDevice*>(this_pointer);
self->streamCB( other_arg );
}
//and in the constructor
int mid = 0;
set_stream_callback(&MyClass::Callback, &mid);
But
error C2664: 'set_stream_callback' : cannot convert parameter 1 from
'void (__cdecl *)(void *,void *)' to 'STREAM_CALLBACK'
How do I get around this?
Edit1: Also, I want to use userdata inside the streamCB callback.
The idea of calling a member function from a callback taking only non-member functions is to create a wrapper for you member function. The wrapper obtains an object from somewhere and then calls the member function. If the callback is reasonably well designed it will allow you to pass in some "user data" which you'd use to identify your object. You, unfortunately, left out any details about your class so I'm assuming it looks something like this:
class MyClass {
public:
void streamCB() {
// whatever
}
// other members, constructors, private data, etc.
};
With this, you can set up your callback like so:
void streamCBWrapper(void* userData) {
static_cast<MyClass*>(userData)->streamCB()
}
int main() {
MyClass object;
set_stream_callback(&streamCBWrapper, &object);
// ...
}
There are various games you can play with how to create the streamCBWrapper function (e.g., you can make it a static member of your class) but all come down to the same: you need to restore your object from the user data and call the member function on this object.
You can achieve what you want to do by turning the userdata into a property of MyClass. Then you don't have to pass it to MyClass::Callback, which would be impossible, since you can only pass one parameter, and it would be the object instance.
Here's an example.
void __stdcall MyClass::streamCB()
{
// callback implementation
}
static void MyClass::Callback(void * this_pointer ) {
MyClass * self = static_cast<MyClass>(this_pointer);
self->streamCB();
}
MyClass::MyClass(void *userdata) {
// do whatever you need to do with userdata
// (...)
// and setup the callback at C level
set_stream_callback(&MyClass::Callback, (void *)this);
}
In your example, the int mid variable would become a property of that class, and thus be accessible from the callback implementation streamCB.
I have a very simple class definition as follows:
#include "../bshttp/controllers.h"
#include <iostream>
#include <string>
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this)
{
m_urlRules["print"] = REG_NAME &DerivedController::print;
//regController(REG_NAME &DerivedController::print,"print");
regController(REG_NAME &DerivedController::printView,"printView");
}
void * print()
{
return NULL;
}
void * printView()
{
cout<<"Print view!"<<endl;
return NULL;
}
};
where either
m_urlRules["print"] = REG_NAME &DerivedController::print;
or
regController(REG_NAME &DerivedController::printView,"printView");
has to be called for all of the member functions. What it does it that it takes the member function pointer of the class and maps with a string, so later on the function can be identified with a string.
Everything is all well and working, but when the class structure gets bigger, the programmer will have to repetitively call this function for every single member function. Is there anyway to use the preprocessor, or any preprocessing library such as the boost-wave, so that the programmer doesn't have to do these repetitive calling?
EDIT:
Sorry for the confusion, I clearly did not describe the problem well enough here.
I am mapping strings to member function pointer;
m_urlRules is a std::map with string as the key, and member function pointer as value
regController is basically a setter function for m_urlRules, so both statements effectively does the same thing, which maps a string to a member function.
REG_NAME is a macro to replace a very ugly typecast.
what I am trying to do is that, if the class where to have the following structure,
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this);
void * print();
void * print2();
void * print3();
void * print4();
};
I dont have to do the following in the constructor:
m_urlRules["print"] = REG_NAME &DerivedController::print;
m_urlRules["print1"] = REG_NAME &DerivedController::print1;
m_urlRules["print2"] = REG_NAME &DerivedController::print2;
m_urlRules["print3"] = REG_NAME &DerivedController::print3;
m_urlRules["print4"] = REG_NAME &DerivedController::print4;
Well, you're trying to build the runtime type information (RTTI) on your own, so no there is no preprocessor macro for this. Mainly because preprocessor macros expand to a single place, and the place where you declare, and the place, where you register your functions are different.
Qt and qmake, does something like this, it finds the functions marked signals/slots, and builds a moc object for RTTI. That's about the best you can get with c++. Other languages like java, and delphi, has more RTTI, than c++, and makes it possible to query functions at runtime.
I am not exactly sure I understood completely your problem, but why don't use the built-in data structure, such as map, in which you can map it to a key (your string).
Here some examples
I would first work on removing the ugly typecast (even in macro form). This can be done by moving the m_urlRules out of BS_Controllers and into an intermediate (or proxy) template class. The template is used to resolve the map to the right derived type. (I didn't know how you defined BS_Controllers, so I made one up.)
class BS_Controllers {
protected:
virtual ~BS_Controllers () {}
public:
virtual void * invokeRule (const std::string &) = 0;
};
template <typename D>
class BS_Proxy : public BS_Controllers {
typedef std::map<std::string, void *(D::*)()> UrlRuleMap;
static UrlRuleMap & urlRules () {
static UrlRuleMap urlRules_;
return urlRules_;
}
void * invokeRule (const std::string &s) {
typename UrlRuleMap::iterator i = urlRules().find(s);
if (i == urlRules().end()) return 0;
return (dynamic_cast<D *>(this)->*(i->second))();
}
protected:
static void regController (void *(D::*m)(), const std::string &s) {
urlRules()[s] = m;
}
};
Now, the DerivedController can be initialized fairly easily, by invoking the regController method of the proxy class.
#define REG_RULE(D, x) BS_Proxy<D>::regController(&D::x, #x)
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
REG_RULE(DerivedController, print);
REG_RULE(DerivedController, printView);
}
};
public:
DerivedController() {
static Populate populate_;
}
void * print() { return NULL; }
void * printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
};
You can view a demo of the above code.
If you want to make the population semi-automatic, you still have to define the list of methods somewhere. You could list them out in a file.
// DerivedController rules
DERIVED_RULE_INC(print)
DERIVED_RULE_INC(printView)
//...
And then change your DerivedController class to use this file:
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
#define DERIVED_RULE_INC(x) REG_RULE(DerivedController, x);
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
}
};
public:
DerivedController() {
static Populate populate_;
}
#define DERIVED_RULE_INC(x) void * x ();
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
};
void * DerivedController::print() { return NULL; }
void * DerivedController::printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
Now, if you add another rule to the file, the registration code and the method declaration is automatic. But the definition of the method needs to be implemented, or a linker error will be generated about the missing method definition.
I believe you want to use this feature for logging reasons, to see where problems appear.
I think you're searching for something like:
urlRules ("<function name>");
regController("<function name>");
Instead of
m_urlRules["<function name>"] = REG_NAME &DerivedController::print;
regController(REG_NAME &DerivedController::printView,"<function name>");
You can define such makros like so:
#define urlRules(x) { m_urlRules[(x)] = REG_NAME &DerivedController::print; }
#define regController(x) { regController(REG_NAME &DerivedController::printView,(x)); }
Attention: I have not tested it, it might not work but in my understanding it should.
EDIT:
Ah now I understand, you want calls for every function within the constructor.
Actually, the constructor is the wrong place, because it gets called for every object you create, but you only have to assign this pointers once. (on startup for example)
See, the functions of a class only exist once in memory, and the thing that is connected to the pointer is the yield data, so all member variables.
There is no simple way to get all class members by name and then run over them, sorry.
At least not as I know of.
But you should keep in mind that the function pointers won't change for any given object.
An external function which does the work would be more intelligent. Called on startup.
I would like to access the data within this member function that is static. Right now the member function is static so that I can use it with a third party API written in C that has typdef function pointer for callback purposes. Based on the info below, what is the best way to get around the need to create a static function in order to use the data from the following function member within other member functions of my class that are non-static. Maybe there is a way to still use this static function but still overcome the inability to mix static with non-static variables. My code does works as is but with no ability to access the data in the following callback function.
void TextDetect::vtrCB(vtrTextTrack *track, void *calldata) /*acts as a callback*/
{
/*specifically would like to take data from "track" to a deep copy so that I don't loose scope over the data withing that struct */
}
In an associated API written in C, there are the following two lines of code that I am forced to use:
typedef void (*vtrCallback)(vtrTextTrack *track, void *calldata);
int vtrInitialize(const char *inifile, vtrCallback cb, void *calldata);
Here is the header of my class:
#include <vtrapi.h>
#include <opencv.hpp>
class TextDetect {
const char * inifile;
vtrImage *vtrimage;
int framecount;
public:
TextDetect();
~TextDetect();
static void vtrCB(vtrTextTrack *track, void *calldata);
int vtrTest(cv::Mat);
bool DrawBox(cv::Mat&);
};
TextDetect::TextDetect() : inifile("vtr.ini")
{
if (vtrInitialize(inifile, vtrCB /*run into problems here*/, NULL) == -1)
std::cout << "Error: Failure to initialize" << std::endl;
vtrimage = new vtrImage;
framecount = 0;
}
void TextDetect::vtrCB(vtrTextTrack *track, void *calldata) /*acts as a callback*/
{
/*specifically would like to take data from "track" to a deep copy so that I don't loose scope over the data withing that struct */
}
I am not sure I understand your precise situation, but here is the standard idiom for wrapping a C++ method into a C callback API:
/*regular method*/
void TextDetect::vtrCB(vtrTextTrack *track)
{
// do all the real work here
}
/*static method*/
void TextDetect::vtrCB_thunk(vtrTextTrack *track, void *data)
{
static_cast<TextDetect *>(data)->vtrCB(track);
}
and then, assuming the function that should call vtrInitialize is also a TextDetect method, you write the call like this:
vtrInitialize(inifile, TextDetect::vtrCB_thunk, static_cast<void *>(this));
I'm writing c++ project, which contains several classes. I created .h file named Position.h, with one array and one function:
class Position
{
public:
Coord positions[25];
public:
void setPos(int index, double x, double y)
{
positions[index].x = x;
positions[index].y = y;
}
};
I want to set values in this array from another classes, so every class in this project will see the same values.
I included "Position.h" in other classes, but i can't access the "positions" array.
Anyone can help me plz??
Just chnage the statement :
Coord positions[25];
to
static Coord positions[25];
also change void setPos
to
static void setPos
while accesing the array ,access it as:
Position::positions[any value]
But before accessing the array,make sure you call the function setPos
positions is a member variable associated with a class instance, and therefore not a global. You can make it similar to a global by making it static. Doing so, it will become a class-scoped variable, and not bound to an instance.
You will need to define it in a single implementation file.
An even better alternative would be having an std::vector<Coord>.
As suggested by others, you can make the members static.
You can also create an instance of the Position class as a global variable, and use that:
Position globalPosition;
void function_using_position()
{
globalPosition.setPos(0, 1, 2);
}
int main()
{
function_using_position();
}
Or make it a local variable, and pass it around as a reference:
void function_using_position(Position &position)
{
position.setPos(0, 1, 2);
}
int main()
{
Position localPosition;
function_using_position(localPosition);
}
I am working on a VS2010C++ console application, and have created a Manager class that holds static, and dynamic objects of the same type (Thing) one of which being a vector.
I originally got an error on the constructor of the manager class stating that the class it was composed of had no default constructor (but it shouldn't have a default constructor because the objects need to be instantiated at run time, and with run time entered information) I ended up creating a default constructor for the held class (that does nothing), and then I was able to continue after that.
then I got done with all the functionality I need for the program, and I get a whole bunch of LNK2019 "something about unresolved external symbol MethodA referenced in functionB.
first why do I need a default constructor for the managed class if I need it to be done at run-time?
second how do I get rid of these LNK2019? (all of these methods are marked inline in the headers, and its only references to, or from the manager class, and there are no naming conflicts.) as a small note could it have something to do with having to mix access modifiers of . (for the static members), and -> (for the dynamic members)?
Edit:
was able to get rid of the default constructor by limiting its need to a single method, and modifying the other statics to dynamic
for the linker error: in Thing.h
class Thing{
public : int ** Array;
public : int size;
public : Point pi;
public : SinglyLinkedList * moves;
...
public :inline bool operator==(const Thing * _thing);
...
};
Thing.cpp
bool Thing::operator==(const Thing * _Thing){
for(int ii = 0; ii < m; ii++){
for(int jj = 0; jj < m; jj++){
if(Array[ii][jj] != _Thing->Array[ii][jj]){
return false;
}
}
}
return true;
}
ThingMgr.h
class ThingMgr {
public : Thing * control;
public : Thing * Current;
public : Thing * previous;
public : int size;
main.cpp
int _tmain{
...
ThingMgr * TestTings= new ThingMgr(num);
...
if(testThings->control->operator==(testThings->Current)){ // pretty sure its here as it is not called anywhere else in the function.
...
}
error
1>Project_1.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Thing::operator==(class Thing const *)" (??8Board##QAE_NPBV0##Z) referenced in function _wmain
I thought it might have been needing to put parentheses in, but then VS yelled about expecting a member. there are other functions, but maybe if I can figure out what is going on here then those should be fixable.
It would help to see the code. From the sounds of it, you create a std::vector<T> with you type which is given some non-zero size: the std::vector<T> needs to initialize the objects and you apparently didn't give it an object it could copy. You might want to create an empty std::vector<T> and use push_back() your readily constructed objects (or emplace() them if you have a C++2011 system)
With respect to link errors: you apparently didn't define some of the functions you are using. What these are exactly is impossible to tell with the vague description you have given. You'd need to provide more details e.g. the exact link error together with the assumed implementation.