I'm developing in C++. I have 2 objects : which are the StandaloneAgent and the ConfigManager.
I want from the Standalone Agent to reach a char * variable in the ConfigManager with a function .
int32_t StandaloneAgent::getConfigFile(char * file){
int32_t code = mConfigMgr->getConfigFile(file);
return code;
}
int32_t ConfigManager::getConfigFile(char * file){
file = mConfigFile;
return 0;
}
Here, the ConfigManager objet is an attribute of the StandaloneAgent with the
ConfigManager * mConfigMgr; variable.
And the file I want to reach is located in the mConfigFile attribute of the ConfigManager.
The problem is :
While putting std::cout,
the mConfigFile in the is OK and
the file variable after the
file = mConfigFile;
is OK
But when I return in the getConfigFile() function of the standalone agent, the file variable is a null pointer and I don't know why.
Is there a C++ specification that I am missing ?
Arguments to functions are either passed by-value or by-reference. Any variable passed by-value will be local to the function and any changes made to it is local to the function too. This means that when to assign a new value to the pointer (file = mConfigFile) you only change the pointer in the function. The pointer you passed as an argument is unaffected.
When taking arguments by-reference, the variable inside the function references the variable used to call the function. Any changes made to that variable will be directly made to the variable used in the call to the function.
In your case, that means that you need to change the ConfigManager::getConfigFile function:
int32_t ConfigManager::getConfigFile(char*& file){
file = mConfigFile; // the change is made to the variable used as an argument
return 0;
}
If the pointer passed to StandaloneAgent::getConfigFile is also supposed to be changed (I assume it is), you need the same change there:
int32_t StandaloneAgent::getConfigFile(char*& file){
int32_t code = mConfigMgr->getConfigFile(file);
return code;
}
Related
i'm implementing a normal function pointer.
so this is the function that i want to call:
WndDyn* Punkt2d::pEditPunkt(WndInfo& wi, Int32 AnzSichtChar, Bool WithUnit,
const DecimalsConf& DecConf)
{
WynDyn_callback Dyncallback;
Dyncallback.AnzSichtChar = AnzSichtChar;
Dyncallback.WithUnit = WithUnit;
Dyncallback.DecConf = DecConf;
return &(DlgZeile(wi)
+ pEditAll(Dyncallback, &pEditFeldX)//pEditFeldX(AnzSichtChar, WithUnit,
DecConf)
+ FntXUnit(2)
+ pEditFeldY(AnzSichtChar, WithUnit, DecConf)
);
}
After defining the function that needs to be called i defined my callee as follow:
WndDyn* pEditAll(WynDyn_callback& Dyncallback, WndDyn* (func_Call)
(WynDyn_callback)) {
return func_Call(Dyncallback);
}
And last of all this is the function that needs to be called using the callee function:
WndDyn* Punkt2d::pEditFeldX(WynDyn_callback Dyncallback) {
return &Edit(pNewStrDataLink(m_x, DLUC_Length, Dyncallback.DecConf),
Dyncallback.AnzSichtChar)
.WithSelAllOnFocus(True);
}
My actuall problem is that my compiler is underlining the function pEditFeldX
in this line pEditAll(Dyncallback, pEditFeldX) in the function pEditpunkt and showing me this Error:
Severity Code Description Project File Line Suppression State
Error C3867 'Punkt2d::pEditFeldX': non-standard syntax; use '&' to
create a pointer to member
Severity Code Description Project File Line Suppression State Error
(active) E0167 argument of type "WndDyn (Punkt2d::)(WynDyn_callback
Dyncallback)" is incompatible with parameter of type "WndDyn
()(WynDyn_callback)"
Because pEditFeldX is a member function you can't just call pEditFeldX(Dyncallback). You must call the function on some Punkt2d object, using e.g. meinPunkt2d.pEditFeldX(Dyncallback).
If you write pEditFeldX(Dyncallback) inside the Punkt2d class then it means (*this).pEditFeldX(Dyncallback). The compiler adds (*this). to save some typing.
A function pointer only points to a function. It doesn't point to a function and an object. It points to pEditFeldX, not meinPunkt2d.pEditFeldX. You must specify the Punkt2d object when you call it.
To remember that a Punkt2d must be specified, a function pointer which points to a member function is declared as this: WndDyn* (Punkt2d::*func_Call)(WynDyn_callback) and called as this: meinPunkt2d.*func_Call(Dyncallback);
If the function pointer is &pEditFeldX then meinPunkt2d.*func_Call(Dyncallback) is the same as meinPunkt2d.pEditFeldX(Dyncallback)
This doesn't apply to static member functions. Static member functions can be used with normal function pointers since no object is required.
It is not quite clear what you are trying to do, but if I understand it right, I think that std::function would be able to solve your problem std::function is able to store anything which can be called, including "half of a function call" like you seem to want. std::bind can make these "half function calls".
You could use them like this:
// in pEditPunkt
pEditAll(Dyncallback, std::bind(&CPunkt2d::pEditFeldX, this, std::placeholders::_1))
// in pEditAll
WndDyn* pEditAll(WynDyn_callback& Dyncallback, std::function<WndDyn* (WynDyn_callback)> (func_Call)
(WynDyn_callback)) {
return func_Call(Dyncallback);
}
First of all i would like to thanks #user253751 for his patient and great support. i would like to share with you how my code look like now:
#include <functional>
// pointer function
WndDyn* pEditAll(WynDyn_callback& Dyncallback, std::function<WndDyn*
(K_WynDyn_callback)>func_Call) {
return func_Call(Dyncallback);
}
//the calle
WndDyn* K_Punkt2d::pEditPunkt( WndInfo& wi, Int32 AnzSichtChar,
Bool WithUnit, const DecimalsConf& DecConf)
{
WynDyn_callback Dyncallback;
Dyncallback.AnzSichtChar = AnzSichtChar;
Dyncallback.WithUnit = WithUnit;
Dyncallback.DecConf = DecConf;
return &(DlgZeile(wi)
+ pEditAll(Dyncallback,
std::bind(&Punkt2d::pEditFeldX, this,
std::placeholders::_1))//pEditFeldX(AnzSichtChar, WithUnit,
DecConf)
+ FntXUnit(2)
+ pEditFeldY(AnzSichtChar, WithUnit, DecConf)
);
}
I am trying to get a handle on HDL to C++ conversions and have hit a bit of a snag.
The conversion using Verilator on Ubuntu is easy enough but one data type is annoying me.
The top code in the hierarchy is...
#include <iostream>
#include "VDorQ24Syms.h"
#include "VDorQ24.h"
using namespace std;
// FUNCTIONS
VDorQ24Syms::VDorQ24Syms(VDorQ24* topp, const char* namep)
// Setup locals
: vm_namep(namep)
, vm_activity(false)
, vm_didInit(false)
// Setup submodule names
{
// Pointer to top level
tOPp = topp;
// Setup each module's pointers to their submodules
// Setup each module's pointer back to symbol table (for public functions)
tOPp->Vconfigure(this, true);
// Setup scope names
}
Passing data to the function
VDorQ24Syms::VDorQ24Syms(VDorQ24* topp, const char* namep)
is what I'm not getting. The second parameter is easy to understand. The first, not so much.
By this I mean, what is the compiler expecting me to pass? Which data type?
I want to pass data like so...
VDorQ24* randomCharacter;
if (VDorQ24Syms(randomCharacter, szAscii) == /*condition*/)
{
return /*value*/;
}
But 'randomCharacter' is uninitialized.
VDorQ24* randomCharacter = /*How do I initialize this?*/;
You example is not complete, but this might help you.
Your variable randomCharacter is not an instance of your class VdorQ24, it's a pointer to your class.
If you want to initialize your variable, set it to nullptr:
VdorQ24* randomCharacter = nullptr; // now you can be 100% certain that it's null.
If you acually wanted to create a new instance of VdorQ24, you can simply forget about the pointer and use values. Here we call the default constructor:
// Not a pointer, initialize the instance of your class directly.
VDorQ24 randomCharacter;
// v---- Here we send a pointer to your variable using the '&' operator.
if (VDorQ24Syms(&randomCharacter, szAscii) == /*condition*/)
{
return /*value*/;
}
If you want to send parameter to the constructor, you can use this syntax:
VDorQ24 randomCharacter{param1, param2};
In fact, any type can be initialized with this syntax, even int and arrays:
int a{1};
float b[] = {1.f, 2.f, 3.f};
I encountered a problem when debugging my model (written in C++) in Eclipse CDT. The problem is that when I pass a structure variable, who contains various member variables such as string or vector, to a function by reference, the value of certain member variables are not updated in the scope of that function. More details are provided as below:
struct ModelConfig {
//... here are some other variables and constructors
vector<int> crop_list;
string path_to_input;
//....
};
Say now I start debugging in GDB, and here is the first function call :
void modelMain::setupModel( const ModelConfig & sim_setting ){
//... some operations to configure the model using 'sim_setting'
/* 1.3 - Initialize the land */
Set_Environment(k_farm_land, sim_setting);
// breakpoint here, printing out the value of 'sim_etting' shows 'sim_setting.path_to_input = "data/"' ; Then I enter into 'Set_Environment' function ...
//...
}
void Set_Environment(vector<Soil> & farm_land, const ModelConfig & sim_setting) {
int EXP_ID = sim_setting.EXP_ID;
string strTmp_a;
strTmp_a = sim_setting.path_to_input + "soil/parameters.txt"; // Problem is here: the GDB shows here that sim_setting.path_to_input = " ". I am expecting strTmp_a = "data/soil/parameters.txt" which now is "soil/parameters.txt" ;
//... operations for reading data
}
The sim_setting.path_to_input variable should hold the string value named data/, which is correct during the call in setupModel(...), but the value is lost (or the address is changed actually) during the call in Set_Environment(...)...
When using the GDB debug in Eclipse to trace the address of the variables, I notice that the address of sim_setting seems correct in both setupModel and Set_Environment, but the member variable of path_to_input and crop_list changed into other place, which cause the lost of data. The value of crop_list is created using .push_back().
I did not get the point since I am passing the variable by reference. The only thing that I can imagine is due to the value assignment of string and vector. Anyone have theory for this ? Thank you very much in advance !
I wonder, is the marked line in the below code correct. Because in this line the result of the function is assigned to the static variable prevRecCallResult (I'll call it "plain assignment"), which is changed inside this function (I'll call it "inside assignment").
Is it guaranteed, that the "inside assignment" is done, when the "plain assignment" executes?
int f(int _n)
{
if (_n >= 1)
{
static int prevRecCallResult;
prevRecCallResult = f(_n - 1); //<-- Is this line Ok?
return prevRecCallResult + 1;
}
else
return _n;
}
I know, the standard says, that a sequence point occurs:
At a function return, after the return value is copied into the
calling context.
, but I'm not sure, this is the answer to my question.
Update:
Considering replies I've received, I should clarify my question:
It's essence is: Is it true, that the prevRecCallResult is not in use by the assignment expression (in marked line) (i.e. is not occupied by it) until f(_n - 1) is finished? (And thus, until this moment, prevRecCallResult is absolutely free for any assignments inside f(_n - 1)?)
static int prevRecCallResult;
prevRecCallResult = f(_n - 1); //<-- Is this line Ok?
Your code is perfectly OK. But just wanted to make you remember that static int prevRecCallResult; executes only once. But prevRecCallResult = f(_n - 1); is assigned after each function call. Once function return prevRecCallResult's at time function's return value will be used in rest of the function.
One more thing, static variable will not die, after you return from function. So prevRecCallResult will not die across function calls.
As I remember all static variables as well as all global variables in C and C++ are assigned automatically to default value for their types - in this particular example default value for 'static int prevRecCallResult' will be 0. So your fears are unfounded (you can easily check this with debugger).
At the same time I cannot understand why you use static variable in this code... is it just simplified code for question or is it real code where you trying to economize memory on automatic variable of recursive function?
/* Thanks to anyone looking at this who might attempt to answer it. I'm really not trying to waste anyone's time here, but I have beat my head on this for about three days. I realize it is probably very simple for someone who understands it. I have tried most every possible combination I can think of and still get compiler errors.
C:\random\RNDNUMTEST.cpp(41) : error C2102: '&' requires l-value
I am trying to pass a pointer as a parameter to a function makeRndmNumber() for the member function fstream.open(). I want to open the file in RNDNUMTEST.cpp and then pass it to makeRndmNumber() so that it can be modified in some way. I have looked online for help, including this website, but I feel like I am overlooking something important or simple or maybe I am just missing the concept altogether.
This isn't for homework, I'm not a college student. Although I did go to school for it, it has been over 10 years since I've done any programming and I never really understood this that well to begin with. Any suggestions would be appreciated.
// These are only excerpts from the actual files.
// RndmNum_Class.h file
typedef void(fstream::*fStream_MPT)(const char*); // fStream_MPT (Member Pointer Type)
class RandomNumber {
public:
RandomNumber();
~RandomNumber() {};
static void loadDigits(double, double, char array[]);
static int getLastNDigits(char array[], int);
static int makeRndmNumber(int, int, fStream_MPT);
};
//*************************************************************8
//RndmNum_Class.cpp file
int RandomNumber::makeRndmNumber(int seed, int _fileSize, fStream_MPT FILE) {
......
}
//**************************************************************/
// RNDNUMTEST.cpp file
#include "RndmNum_Class.h"
int main() {
const char* RNDM_FILE = "c:\\RandomFile.txt";
fstream FStream_Obj;
// FStream_Obj.open(RNDM_FILE);
fStream_MPT FileMembPtr = &FStream_Obj.open(RNDM_FILE);
//fStream_MPT FileMembPtr = &fstream::open;
int seed = 297814;
int size = 20000;
cout << RandomNumber::makeRndmNumber(seed, size, FileMembPtr);
return 0;
}
This: &FStream_Obj.open(RNDM_FILE) is not taking the address of the function, it's trying to take the address of the return value of a call to that function. But that function returns void, hence the error message.
First, change the function definition from typedef void(fstream::*fStream_MPT)(const char*); to typedef void(fstream::*fstream_MPT)(const char*,ios_base::openmode), there is a default parameter you are forgetting.
Change the fStream_MPT FileMembPtr = &FStream_Obj.open(RNDM_FILE); to fStream_MPT FileMembPtr = &fstream::open; as per your comment, and add an additional parameter to makeRndNumber, a pointer to an fstream to operate on.
int RandomNumber::makeRndmNumber(int seed, int _fileSize, fStream_MPT FILE, fstream *file)
{
((*file).*FILE)("ExampleText",ios_base::in | ios_base::out);
}
FILE = fstream::open;
EDIT
This could also be done a little cleaner with std::function objects.
First redefine your type.
typedef std::function<void(const char*)> fStream_MPT;
Then when you assign, be sure to bind your objects.
fStream_MPT FILE = std::bind(&fstream::open,&file,std::placeholders::_1, ios_base::in | ios_base::out);
Then in your function you simply call the function
int RandomNumber::makeRndmNumber(int seed, int _fileSize, fStream_MPT FILE)
{
FILE("Example text");
}
It doesn't make any sense: member function pointers is used so you can apply different member functions somewhere without knowing which exact function is called. It is like passing the function's name around (except that the name is resolved at compile-time). It doesn't seem that this is what you want to do!
Even if you would correctly obtain the function's address (rather than trying to get the address of the result of calling open()), it wouldn't work because std::fstream::open() takes two arguments: the second argument is for the open-mode and it is defaulted to std::ios_base::in | std::ios_base::out.
I'm not quite sure what you really want to d but it seems you want to pass the file stream around. The normal way to do this is to pass a reference to a std::iostream as argument to the function. Well, actually you probably want to use a std::ifstream initially and hence pass the argument as std::istream&.