I have this function callback that receives a param of type T. T has a member function, GetData(), defined as below, which returns data to be used within the callback:
void Callback(T* t) {
int64_t val;
auto data = t->GetData();
memcpy(&val, data, 8);
std::cout << "Value: " << val;
}
// Member of a class T:
char mData[64];
// Member functions of T
const char* GetData() const { return mData; }
void SetData(void* data, uint8_t size) {
if (size > 0) {
memcpy(mData, data, size);
}
}
The above works fine. However, for some reason, I can't seem to pass a 'this' pointer of a class within the data component. This is how the data is copied to the mData member.
// This works
char data[64];
int64_t val = 42;
memcpy(&data, &val, 8);
t->SetData(data, 8);
// For storing 'this', I tried variations of the below.
char data[64];
memcpy(&data, this, 8);
t->SetData(data, 8);
// t->SetData(this, 8);
When I try to store 'this' in the data, and then try to get it back in the callback, I can't seem to get the this pointer's value correctly. I tried variations of the below, including reinterpret_cast and others.
void Callback(T* t) {
TypeOfThis* self;
auto data = t->GetData();
memcpy(&self, data, 8);
// self has bogus values.
}
How can I pass a 'this' pointer correctly, in the case above?
firstly "this" is to be used inside a class. 2ndly: "this" address does not necessarily point to the first data member of the class as there are some admin data subject to the compiler implementation, in other words there may be a few bytes gap between "this" and its first data member.
Related
Here is what I would like to do:
std::stringstream s;
s<<"Some "<<std::hex<<123<<" hex data"<<...;
Having this s, I would very much like to pass it around, and that is possible easily. However, at some point, there is a need to (conceptually) pass it to an interface that only accepts const void */size_t pair which describes the memory region.
As far as I see (would love to stand corrected), there is no way to do that with 0-copy in C++17 and below. One must use .str() which will create a string copy and then take it from there.
As a "hack", this is what I came up with:
struct stringstream_extractor_t {
// this structure will be used to get access to pbase member function which is protected
// the way we do that is to inherit from it
template <typename T>
struct accessor_t : public T {
static const char* data(const accessor_t* pT) { return pT->pbase(); }
};
// get the return type for std::stringstream::rdbuf
using bufferType = std::remove_pointer<decltype(((std::stringstream*)nullptr)->rdbuf())>::type;
// having the std::stringstream::rdbuf result type, we can now create our accessor type
// which will be able to call pbase inside it
using accessorType = accessor_t<bufferType>;
// this is where we deposit the data, in a const manner
const std::string_view _data;
// syntactic sugar: init the _data with the stuff from stream reference
stringstream_extractor_t(std::stringstream& stream) : _data{getBuffer(stream), static_cast<size_t>(stream.tellp())} {}
// syntactic sugar: init the _data with the stuff from stream pointer
stringstream_extractor_t(std::stringstream* pStream) :
_data{pStream ? getBuffer(*pStream) : nullptr, pStream ? static_cast<size_t>(pStream->tellp()) : 0} {}
// this uses the accessor type to grab access to data
static const char* getBuffer(const std::stringstream& stream) {
// we get the buffer and we cast it to our accessor type. This is safe, as we do not
// have any members inside it, just a static function
const accessorType* pBuffer = reinterpret_cast<accessorType*>(stream.rdbuf());
// grab the data now
return accessorType::data(pBuffer);
}
// convenience functionality
inline const char* data() const { return _data.data(); }
inline size_t size() const { return _data.size(); }
};
And here is how it is used, with a C-like interface
std::stringstream s;
s << "Hi there! " << std::hex << 0xdeadbeef;
const stringstream_extractor_t e(s);
write(2, e.data(), e.size());
Yes, I'm aware of the fact that the pointers must be kept alive (the std::stringstream instance), and all the life cycle implications.
Is there a more comfortable non-convoluted way to achieve this quite basic thing: get a buffer out from an output stringstream with move semantics.
I'm clearly missing something, this should not be this hard.
https://godbolt.org/z/G53P6oocb
Well in C++ 20 you could do this
#include <iostream>
#include <ios>
#include <sstream>
void c_style_func(const char* cp, std::size_t size) {
std::cout << std::string_view (cp,size) << "\n";
}
int main() {
std::stringstream s;
s << "Hi there! " << std::hex << 0xdeadbeef;
auto view = s.view();
c_style_func(view.data(), view.size());
}
using § 29.8.2.4 Page of the standard 1411
basic_string_view<charT, traits> view() const noexcept;
11 Let sv be basic_string_view<charT, traits>.
12 Returns: A sv object referring to the basic_stringbuf’s underlying character sequence in buf:
(12.1) — If ios_base::out is set in mode, then sv(pbase(), high_mark-pbase()) is returned.
(12.2) — Otherwise, if ios_base::in is set in mode, then sv(eback(), egptr()-eback()) is returned.
(12.3) — Otherwise, sv() is returned.
13 [Note: Using the returned sv object after destruction or invalidation of the character sequence underlying
*this is undefined behavior, unless sv.empty() is true. —end note]
Is it possible to pass a function pointer as the parameter for the freeRTOS xTaskCreate function?
I suspect I need to cast the void* pvParameters within the task before I can call it but I am not sure what such as cast would be.
class param
{
private:
//Initialized during construction to hardware specific value.
uint8_t mParam = 0;
public:
uint_8 getParam() {return mParam;}
};
void task(void* pvParameters)
{
//get hardware specific pvParameters.
uint8_t hwParam = pvParameters();
// Do task things.
}
main()
{
param p;
uint32_t result;
result = xTaskCreate(task, "Task", configMINIMAL_STACK_SIZE, (void *)&p.getParam, configMAX_PRIORITIES - 1, nullptr); //lint !e712 implicit conversion from long to int
if (result == 0)
{
//print error msg.
}
else
{
vTaskStartScheduler();
for(;;) {ASM("NOP");}
}
}
Why not using &p (address of object p) as argument to access the complete param object using a cast like this:
param& p = *(param*)pvParameters;
Beware that for a number of ports/MCUs the main stack is reused as ISR stack and main stack allocated arguments might get corrupted. Better use e.g. static/new param object.
I am trying to build an application that can dynamically call any Win32 API function according to user input.
I am wondering how can I have behavior of the function RegisterCallback in C++, because it seems very useful and it can get the address to a callback function.
How can I achieve a same behavior with a function like it in C++?
I already successfully implemented a function which can call any dynamic library, but stuck in such dynamic callbacks.
For example I can call EnumWindows API with my function like below:
CallLibFunction(GetProcAddress(LoadLibrary(L"User32.dll"), "EnumWindows"), ParamArray, 2, ExepInfo);
Thanks in advance.
EDIT: I will explain more.
Assume I have following code:
Callback function:
BOOL CALLBACK EnumWindowsProc(__in HWND hWnd, __in LPARAM lParam)
{
return TRUE;
}
Main Function:
EnumWindows(EnumWindowsProc, NULL);
Above is the usual way anyone can use the API function. I want it to be called like this:
LONGLONG CallbackAddress = <Some Function to get address>&EnumWindowsProc
ParamArray[1].type = VT_I8;
ParamArray[1].llval = CallbackAddress; // Address of `EnumWindowsProc`.
And then finally call it dynamically like:
CallLibFunction(GetProcAddress(LoadLibrary(L"User32.dll"), "EnumWindows"), ParamArray, 2, ExepInfo);
First, you need to declare a pointer type to hold the address of your callback. The basic definition of a function is a bit odd in c++. There is a further complication that in C++ we have functions, function-objects, and template types.
The standard provides a basic function template type:std::function. This type
holds not a function pointer, but a callable object.
#include <functional>
To declare a specific function type, pass its signature to std::function as its template parameter.
typedef std::function<int(const char*)> StdFreeFunc;
// you can also define types for member functions, and define
// member function pointers this way
struct A{};
typedef std::function<int A::*(const char*)> StdMemberFunc;
// member callable objects are called with this syntax:
// (obj.*callable)(args); or (obj->*callable)(args);
// the parenthesis are often required to keep the compiler happy
// A callable object:
struct CallMe
{
int xy;
int operator()(const char*) { /*...*/ return xy; }
};
std::function is compatible with function objects, lambdas and regular function pointers (see below). Works best with C++ only stuff.
struct AStruct
{
StdFreeFunc callback_; // we hold a value, not a pointer
void setCallback(StdFreeFunc&& cb) // pass by value, reference, const ref,
{ // move... like any object type
callback_ = cb;
};
int callCallback(const char* str)
{
if (callback_) // callable object has a bool() operator to check if valid !!
return (callback_)(str);
// the parenthesis and is optional, so this is the same:
if (callback_)
return callback_(str):
}
};
// example with callable object:
AStruct as, ar;
as.setCallback(CallMe{42}); // we can pass an object with data
ar.setCallback(CallMe{84}); // to obtain different effects
as.callCallback("prints fourty two");
ar.callCallback("prints eighty four");
C-style function pointers
Before C++, there was C. THis is how it's done in C, and it does compile. The disadvantage with C-style function pointers is that they are not compatible with function objects. On the other hand they are compatible with C, and many other languages such as PASCAL, VB, etc..
For example, the type a function taking a const char* as a parameter and returning an int is written as:
typedef int (CallBack)(const char*);
The most usual form is to declare a pointer, since that's what is stored. As in:
typedef int (*CallBack)(const char*);
// you can specify extra call specifications
typedef int (__stdcall * CallBack)(const char*); // uses PASCAL calling
// exmample:
struct YourStruct
{
//...
Callback callback_{nullptr}; // this is a pointer initialize to nullptr
//...
void setCallback(Callback cb)
{
// call as ys.setCallback(AFunction)
// or ys.setCallback(&AFunction)
callback_ = cb;
};
int callCallback(const char* str)
{
if (callback_) // always check if valid !!
return (*callback_)(str);
// the parenthesis and the * are optional, so this is the same:
if (callback_)
return callback_(str):
}
};
int UserFunction(const char*) { /*...*/ return 0; }
YourStruct ys;
ys.setCallback(&UserFunction);
ys.callCallback("hello");
Reading your link, the following is said about the callback address:
If the exe running the script is 32-bit, this parameter must be between 0 and 4294967295. If the exe is 64-bit, this parameter can be a 64-bit integer.
So, you need to convert your pointer address to an integer type. Drawing some inspiration from this answer, the following code should give you a hint how to do the conversion in your case:
#include <iostream>
#include <cstdint>
bool f() {
return true;
}
int main() {
int iv = *((int*)(&f));
long lv = *((long*)(&f));
long long llv = *((long long*)(&f));
intptr_t ipv = *((intptr_t*)(&f));
std::cout << "int: " << iv << std::endl;
std::cout << "long: " << lv << std::endl;
std::cout << "long long: " << llv << std::endl;
std::cout << "intptr_t: " << ipv << std::endl;
}
For me this prints:
int: -443987883
long: 82192552476362837
long long: 82192552476362837
intptr_t: 82192552476362837
Note here that an int is to small to cover the void* value. You should be able to convert properly with LONGLONG as well, otherwise intptr_t seems to be the correct data type.
The answer is probably stupidly easy, but I have stared at this code for quiet a while now and I simply can't find the solution.
Here is my problem. I have a pointer to a base class. Then I call a function to find an element in a vector of objects derived from that class. The pointer is passed as a parameter and filled with the found object. If I try to read a member variable of what the pointer points to I get a SIGSEV.
This is the code:
Base* control;
if(findControlByName("aName", control)) {
std::cout << control->name << std::endl; // SIGSEV happens here
}
//...
bool findControlByName(std::string name, Base* control) {
for(size_t i = 0; i < controls.size(); i++) {
if(controls[i]->name == name) {
control = controls[i];
std::cout << control->name; // this works
return true;
}
}
return false;
}
How do I do this properly?
To elaborate on my above comment, when you assign a value to a pointer parameter in a function, that value is local to the scope of the function, just like any other parameter that is passed by value. Assigning a value to the parameter in the scope of the function does not change it outside the scope of that function unless it is passed by reference.
An example:
void someFunc(int * x)
{
static int my_static = 5;
x = &my_static;
}
void someFunc2(int * &x)
{
static int my_static_2 = 7;
x = &my_static_2;
}
//somewhere else:
int * ptr;
someFunc(ptr);
//ptr is unchanged/still uninitialized
someFunc2(ptr);
//ptr points to my_static_2
If the signature of someFunc is changed to take a reference parameter, the parameter will be passed by reference instead of passed by value.
I having difficulty saving a pointer argument that my mock receives.
#define SIZE_OF_DATA
typedef struct {
uint32_t someValue1;
uint16_t someValue2;
// other values here
} LargeStruct;
class SomeClass {
public:
// assume sendData is a generic function where data is actually pointer to a LargeStruct
void sendData(const uint8_t* data, const uint16_t size);
}
class MockClass : public SomeClass {
public:
MOCK_METHOD2(sendData, void(const uint8_t*, const uint16_t));
};
I want to save the first argument to sendData (the pointer) and look at the data it points to (it points to a large struct, so I don't want to copy by value):
TEST(SomeFixture, sendData_checkSentDataIsValid) {
MockClass mock;
const uint8_t *pData;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA)).WillOnce(SaveArg<0>(&pData));
// do something here that calls sendData()
// hopefully data should point to the same data that was passed in to the method
LargeStruct *ls = (LargeStruct *)pData;
// now verify that the data is ok...
// some expectations here
EXPECT_EQ(SOMEVALUEIWANT, ls->someValue1);
}
However, the data pointed to by pData is wrong - I think I appear to be saving the pointer value into the struct, rather than saving the pointer.
I think the problem lies in the variable I pass to SaveArg, but I can't seem to get it in a version that compiles and gives me the correct answer. Any pointers please?
I just ran into the same situation, and in my case, I had to make sure that the pointer passed into the equivalent of your sendData() function was not pointing to an automatic variable on the stack. Otherwise, by the time you access the pointer, the contents will have changed. I found that less than helpful, so I decided to define a customized alternative to SaveArg like this:
ACTION_TEMPLATE(SaveSomeValue1,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer))
{
const void * data = ::std::tr1::get<k>(args);
const LargeStruct* ls = (const LargeStruct *)data;
*pointer = ls->someValue1;
}
You can then use it like this:
uint32_t someValue1;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA))
.WillOnce(SaveSomeValue1<0>(&someValue1));
//...
EXPECT_EQ(SOMEVALUEIWANT, someValue1);
You can create one void pointer as a buffer and save argument inside that buffer. After that you should cast the buffer to your large structure.
TEST(SomeFixture, sendData_checkSentDataIsValid) {
MockClass mock;
LargeStruct *ls;
void *buffer;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA))
.WillOnce(SaveArg<0>(&buffer));
// do something here that calls sendData()
ls = static_cast<LargeStruct *>(buffer);
EXPECT_EQ(SOMEVALUEIWANT, ls->someValue1);
}