I need to keep some information about each function in my program in the form of a constant number. I was wondering if it is possible to put the constant for a function just before it in the code memory, so if a function is called through a function pointer, that information could be read by subtracting the value of the function pointer.
To illustrate further, my code memory should look as follows.
ConstantForFunc1
Func1:
....
ConstantForFunc2
Func2:
....
And following is an example code of how I would read that information
FuncPointer f = &Func2;
int constantForFunc2 = *((int*)(f - sizeof(int)));
And note that using Hash tables is too slow for what I'm trying to achieve, so I need a very fast method. And all this modification, which is inserting constants and code to read from them is done by a compiler pass, which I'm writing and which modifies the LLVM IR. Using structures would be too cumbersome for the compiler pass, as it would have to modify a lot of code.
What you are doing doesn't make sense, yet:
You could use structs maybe?
struct example
{
int constantForFunc;
void (*ptrToFunc)();
};
//After declaring, maybe 3, functions
struct example funcList[3] = {{5, &func1}, {10, &func2}, {15, &func3}};
int currentFuncConstant=funcList[1].constantForFunc;
(*funcList[1].ptrToFunc)();
I haven't used function pointers to be honest, probaby has mistakes.
Is this not acceptable at all?:
#include <iostream>
using namespace std;
const int Const__Fxn1 = 1;
void Fxn1()
{
cout << "Fxn1" << endl;
}
const int Const__Fxn2 = 2;
void Fxn2()
{
cout << "Fxn2" << endl;
}
#define GetFxnConst(FxnName) Const__ ## FxnName
int main()
{
cout << GetFxnConst(Fxn1) << endl;
cout << GetFxnConst(Fxn2) << endl;
return 0;
}
Option 2:
#include <iostream>
#include <cstring>
using namespace std;
const volatile int v1 = 0;
volatile unsigned v2 = 0;
void Fxn1()
{
if (v1) { v2 = 0x12345601; }
cout << "Fxn1" << endl;
}
void Fxn2()
{
if (v1) { v2 = 0x12345602; }
cout << "Fxn2" << endl;
}
int FindFxnConst(void(*f)())
{
const unsigned char* p = (const unsigned char*)f;
while (memcmp(p, "\x56\x34\x12", 3))
p++;
return p[-1];
}
int main()
{
Fxn1();
cout << FindFxnConst(Fxn1) << endl;
Fxn2();
cout << FindFxnConst(Fxn2) << endl;
return 0;
}
Output (Ideone):
Fxn1
1
Fxn2
2
You can embed more than 8 bits of data per function by using other magic prefixes, e.g.:
if (v1)
{
v2 = 0x12345611; // byte 1
v2 = 0x789ABC22; // byte 2
v2 = 0xDEF01233; // byte 3
v2 = 0xFEDCBA44; // byte 4
}
This is not necessarily a reliable solution, let alone portable.
Since the addresses of the functions are known from the executable binary (unless they are loaded from a shared library ofcourse), if you have the address space layout randomization (ASLR) off, you could use gperf to generate a highly efficient hash function for you and use that hash function to get the constants for each function.
However, for this, you will have to compile your program twice, first to get the addresses of the functions from the generated binary, so that you could give those addresses as an input to gperf and recompile using the hash function generated by gperf. But you have to be careful that the addresses of the functions from the first compilation do not become different in the second compilation. I am not sure, how to achieve that.
An alternative, would be to do something like gperf just after your program is loaded, so you don't have to compile twice. But I don't know how to do that.
Related
I'm trying to run MATLAB from C++ and return the MATLAB output in a structure to C++. The structure could contain any number of things, including arrays of different dimensions and lengths. There's a similar question here, but the answer doesn't give enough detail for me to understand and extrapolate.
I'm running MATLAB using the MatlabEngine.hpp and MatlabDataArray.hpp. I need to return a lot of outputs and have tried other methods which don't quite do what I'm after. Using a structure seems the most logical / readable way to do things. I'll try to explain my case with the following examples, which are hopefully written in a way which will be most useful for anyone else with a similar problems.
MWE 1 - return n by n array
MATLAB code
function output = simple_fun1(a, bc)
% Takes input values of a and an array [a,b]
b = bc(1);
c = bc(2);
sum = a+b+c;
prod = a*b*c;
output = [sum, prod; 3, 4];
This can be run using the C++ code:
C++ code
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
int main()
{
using namespace matlab::engine;
matlab::data::ArrayFactory factory; // Create MATLAB data array factory
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
matlabPtr->eval(u"addpath(genpath('C:/Users/...your path here...'))"); // Add the path to where MATLAB functions are.
std::vector<double> bc{ 10, 13};
std::vector<matlab::data::Array> args({
factory.CreateScalar<double>(7),
factory.CreateArray({ 1, 2 }, bc.cbegin(), bc.cend())
});
matlab::data::TypedArray<double> results = matlabPtr->feval(u"simple_fun1",args); // Run simple_fun1
std::cout << "Sum: " << results[0][0] << std::endl;
std::cout << "Prod: " << results[0][1] << std:endl;
std::cout << "Three: " << results[1][0] << std::endl;
}
This works for a single return of an n by n array. But if I want to return data separately, i.e. function [sum, prod] = simple_fun1(a,bc) it doesn't work.
MWE2 - return multiple outputs
I've managed to return multiple outputs using tuples, but then I can only access the first element of the array (if it was an array output) since I've been unable to define a tuple of MATLAB arrays. For example
MATLAB code
function [sum, prod] = simple_fun2(a, bc)
% Takes input values of a and an array [a,b]
b = bc(1);
c = bc(2);
sum = a+b+c;
prod = a*b*c;
C++ code
std::tuple<double, double> results;
results = matlabPtr->feval< std::tuple<double, double>>(u"simple_fun2", double(7), std::vector<double>{ 10, 13}); // Just as another example of how to enter inputs in case that's helpful for anyone.
double s;
double p;
std::tie(s, p) = results;
std::cout << "Sum: " << s << ", Prod: " << p << std::endl;
Return structure
Instead, I would like to write my MATLAB function so that it returns a structure, which should hopefully simplify the code for large amounts of data being passed and allow the data to have different dimensions. However, I've been unable to create a working example.
MATLAB code
function output = simple_fun3(a, bc)
b = bc(1);
c = bc(2);
output.sum = a+b+c;
output.prod = a*b*c;
output.a_sq = a*a;
output.b_sq = b*b;
C++ code
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
int main()
{
using namespace matlab::engine;
matlab::data::ArrayFactory factory; // Create MATLAB data array factory
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
matlabPtr->eval(u"addpath(genpath('C:/Users/...your path here...'))"); // Add the path to where MATLAB functions are.
std::vector<double> bc{ 10, 13};
std::vector<matlab::data::Array> args({
factory.CreateScalar<double>(7),
factory.CreateArray({ 1, 2 }, bc.cbegin(), bc.cend())
});
matlab::data::StructArray my_matlab_struct = factory.createStructArray(matlab::data::ArrayDimensions{ 1, 4}, std::vector<std::string>{'sum', 'prod', 'a_sq', 'b_sq'});
my_matlab_struct = matlabPtr->feval(u"simple_fun3",args);
The above C++ code doesn't work and I don't understand how the structure is being defined; i.e. what the ArrayDimensions are dimensions of. Any help is appreciated. Thanks
After much searching I managed to solve the problem and pass structures between C++ and MATLAB. The solution is based on this, but the code at the link doesn't work due to missing namespaces. Therefore I've put the solution below. Note: the solution assumes you already have MATLAB and C++ setup to interface with each other, which can be a whole other process depending your MATLAB version and, if you're using Visual Studio, your Visual Studio version too.
Pass a structure to MATLAB from C++
Not part of my original question, but this may be useful to someone.
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
#pragma comment (lib,"libmat.lib")
#pragma comment (lib,"libmx.lib")
#pragma comment (lib,"libmex.lib")
#pragma comment (lib,"libeng.lib")
int main()
{
using namespace matlab::engine;
matlab::data::ArrayFactory factory; // Create MATLAB data array factory
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
matlabPtr->eval(u"addpath(genpath('Insert the path of any MATLAB functions you plan to use'))")
matlab::data::StructArray my_structure = factory.createStructArray({1, 1},{"x","y","z"}); // Create a structure with one element and fields x,y,z
my_structure[0]["x"] = factory.createArray({1, 3},{1., 2., 3.});
my_structure[0]["y"] = factory.createArray({1, 3},{1., 4., 9.});
my_structure[0]["z"] = factory.createArray({1, 3},{1., 8., 27.});
matlabPtr->setVariable(u"Mstruct",my_structure); // pass structure to matlab workspace
matlabPtr->eval(u"Mstruct") // show the structure exists.
// The array can be passed to a function using feval
}
Get a structure returned from a function
The code below assumes the MATLAB engine is already set up and gets a structure returned from a MATLAB script called matlab_fun which accepts the input(s) args.
matlab::data::StructArray my_matlab_struct = matlabPtr->feval(u"matlab_fun",args);
matlab::data::ArrayDimensions dims = my_matlab_struct.getDimensions();
std::cout << "Structure is: " << dims[0] << " by " << dims[1] << std::endl;
size_t numFields = my_matlab_struct.getNumberOfFields();
std::cout << "Structure has " << numFields << " fields." << std::endl;
matlab::data::Range<matlab::data::ForwardIterator, matlab::data::MATLABFieldIdentifier const> fields = my_matlab_struct.getFieldNames();
for (int i=0; i<numFields; i++){
matlab::data::TypedArray<double> data = my_matlab_struct[0][fields.begin()[i]]; // [0] for the first element of the structure. Iterates over the fields.
matlab::data::ArrayDimensions data_dims = data.getDimensions();
for (int j=0; j<data_dims[0];j++){
for (int k=0; k<data_dims[1];k++){
std::cout << data[j][k] << " ";
}
std::cout << std::endl;
}
}
This is a particularly strange question, but i'm attempting to write a function that swaps the values of two integers without using references or '&'. I don't see how this is even possible. Here's what I have so far.
void swap (int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
This, normally would be the way that I would do it, but since the integers don't permanently change, I have no idea as to how I would do this without referencing. Any suggestions?
Thanks!
You should correct the question title. It says “using references”. That’s the opposite of what you mean, apparently.
Assuming that:
truly no references and pointers allowed, exluding any wrapper tricks
a runtime swap is what you want – as opposed to compile time template trickery
no classes, because that would trivial
I can think of one utterly horrible solution. Make your ints globals.
ridiculous_swap.hpp
#ifndef RIDICULOUS_SWAP_HPP
#define RIDICULOUS_SWAP_HPP
extern int first;
extern int second;
void swap_ints();
#endif // RIDICULOUS_SWAP_HPP
ridiculous_swap.cpp
int first = 0;
int second = 0;
void swap_ints()
{
auto tmp = first;
first = second;
second = tmp;
}
main.cpp
#include "ridiculous_swap.hpp"
#include <iostream>
int main()
{
first = 23;
second = 42;
std::cout << "first " << first << " second " << second << "\n";
// prints: first 23 second 42
swap_ints();
std::cout << "first " << first << " second " << second << "\n";
// prints: first 42 second 23
}
It’s not useful for anything, but it does swap two integers without using references or pointers.
There is this old trick to swap two integer-like variables without using a temporary variable:
void swap(int& a, int& b)
{
a ^= b;
b ^= a; // b ^ (a ^b) = a
a ^= b; // (a ^ b) ^ a = b
}
Im having this really weird error during run-time.
My program takes two parameters, does some math calculus with them and std::cout's the values in the end.
My program works if i input somevalues, but if i input other values it says that a variable is being used without being initialized, which i think it makes no sence.
Here is the code:
#include <iostream>
#include <stdio.h>
#include <cmath>
double align_nb(int n) { return { ceil(n / 512.0)*512.0 }; } // bytes
double align_pt(int k) { return { floor(k / 512.0)*512.0 }; } // pointer
int main(int argc, char * argv[])
{
int o_n = std::atoi(argv[1]); // original number
int o_p = std::atoi(argv[2]); // original pointer
int max_bytes, new_pointer; // max bytes to read, new pointer to point
float log = (std::log(o_n) / std::log(2));
if (log != floor(log))
{
max_bytes = align_nb(o_n); // bytes alinhados para a frente
new_pointer = align_pt(o_p); // ponteiro alinhado atrás
}
else if (log == floor(log))
{
new_pointer = align_pt(o_p);
if (max_bytes + (o_p - new_pointer) >max_bytes)
{
max_bytes += 512;
}
}
std::cout << "Original bytes= " << o_n << std::endl;
std::cout << "Original pointer= " << o_p << std::endl;
std::cout << "Max_bytes= " << max_bytes << std::endl;
std::cout << "new_pointer= " << new_pointer << std::endl;
return 0;
}
Here are the values i tested it and it crashed, giving me that run-time error:
2048 513
1024 500
here is one example of values were the code doesnt give me that error and the program works:
513 520
Here is a print of the error it gives me.
I'd really appreciate someone explaining me why it gives me that error/how to fix it.
Regardless, thanks!
(PS: math tag is included cause it could be the math in the program that is causing it to crash. If annyone thinks it shoudlnt be used in this question, let me know in the comments and ill remove it.)
(PS 2: the variable it complains when it gives me the run time error is 'max_bytes'.)
If your code takes the else path at line 17, then your code doesn't initialize max_bytes, but uses it afterwards. That's the problem.
Notes:
comparing calculated floating point values for equality usually a bad practice
you don't need the additional if at line 23.
Make sure that for each path your code takes the values of the variables you use are initialized. If you don't you get what is called Undefined Behaviour. There could be anything in an uninitialized variable.
int max_bytes;
....
....
expression_involving_max_byte <- Dangerous!
I'm developing a application and my idea is store "apps" in files, like executables. Now i have that:
AppWriter.c
#include <vector>
#include <time.h>
#include <functional>
struct PROGRAM
{
std::vector<int> RandomStuff;
std::vector<std::function<void()>> Functions;
std::function<void()> MAIN;
} CODED;
void RANDOMFUNC()
{
srand(time(NULL));
for(int i = 0; i < 40; i++)
CODED.RandomStuff.push_back(rand() % 254);
}
void LOGARRAY()
{
for(int i = 0; i < CODED.RandomStuff.size(); i++)
std::cout << "["<< i + 1 <<"]: "<< CODED.RandomStuff[i] << std::endl;
}
void PROGRAMMAIN()
{
std::cout << "Hello i call random function!" << std::endl;
CODED.Functions[0]();
CODED.Functions[1]();
}
void main()
{
CODED.MAIN = PROGRAMMAIN;
CODED.Functions.push_back(RANDOMFUNC);
CODED.Functions.push_back(LOGARRAY);
std::cout << "Testing MAIN" << std::endl;
CODED.MAIN();
FILE *file = fopen("TEST_PROGRAM.TRI","wb+");
fwrite(&CODED,sizeof(CODED),1,file);
fclose(file);
std::cout << "Program writted correctly!" << std::endl;
_sleep(10000);
}
AppReader.c
#include <iostream>
#include <vector>
#include <time.h>
#include <functional>
struct PROGRAM
{
std::vector<int> RandomStuff;
std::vector<std::function<void()>> Functions;
std::function<void()> MAIN;
} DUMPED;
void main()
{
FILE *file = fopen("TEST_PROGRAM.TRI","rb+");
fseek(file,0,SEEK_END);
int program_len = ftell(file);
rewind(file);
fread(&DUMPED,sizeof(PROGRAM),1,file);
std::cout
<< "Function array size: " << DUMPED.Functions.size() << std::endl
<< "Random Stuff Array size: " << DUMPED.RandomStuff.size() << std::endl;
DUMPED.MAIN();
}
When i run AppReader the functions dont work(Maybe why std::function it's like void pointers?), but in arrays or if i add variables i can see with debugger the data are storaged correctly (for that i tryed the vector of functions), but whatever doesn't work throw's me error on functional file. ¿Any ideas how i can do that?
This is never going to work. At all. Ever. std::function is a complex type. Binary reads and writes don't work for complex types. They never can. You would have to ask for functions in a pre-defined serializable format, like LLVM IR.
Your problem is that you're storing information about functions that exist in one executable, then trying to run them in a separate executable. Other than that, your code does work, but as DeadMG says, you shouldn't be storing complex types in a file. Here's how I modified your code to prove that your code works if run within a single executable:
#include <iostream>
#include <vector>
#include <time.h>
#include <functional>
struct PROGRAM
{
std::vector<int> RandomStuff;
std::vector<std::function<void()>> Functions;
std::function<void()> MAIN;
} CODED;
void RANDOMFUNC()
{
srand(time(NULL));
for(int i = 0; i < 40; i++)
CODED.RandomStuff.push_back(rand() % 254);
}
void LOGARRAY()
{
for(int i = 0; i < CODED.RandomStuff.size(); i++)
std::cout << "["<< i + 1 <<"]: "<< CODED.RandomStuff[i] << std::endl;
}
void PROGRAMMAIN()
{
std::cout << "Hello i call random function!" << std::endl;
CODED.Functions[0]();
CODED.Functions[1]();
}
int main()
{
CODED.MAIN = PROGRAMMAIN;
CODED.Functions.push_back(RANDOMFUNC);
CODED.Functions.push_back(LOGARRAY);
std::cout << "Testing MAIN" << std::endl;
CODED.MAIN();
FILE *file = fopen("TEST_PROGRAM.TRI","wb+");
fwrite(&CODED,sizeof(CODED),1,file);
fclose(file);
std::cout << "Program writted correctly!" << std::endl;
// _sleep(10000);
std::cout << "---------------------\n";
file = fopen("TEST_PROGRAM.TRI","rb+");
fseek(file,0,SEEK_END);
int program_len = ftell(file);
rewind(file);
fread(&CODED,sizeof(PROGRAM),1,file);
std::cout
<< "Function array size: " << CODED.Functions.size() << std::endl
<< "Random Stuff Array size: " << CODED.RandomStuff.size() << std::endl;
CODED.MAIN();
}
The problem is not that you're storing complex types via binary read/write, per se. (Although that is a problem, it's not the cause of the problem you posted this question about.) Your problem is that your data structures are storing information about the functions that exist in your 'writer' executable. Those same functions don't even exist in your 'reader' executable, but even if they did, they likely wouldn't be at the same address. Your data structures are storing, via std::function, pointers to the addresses where the functions exist in your 'writer' executable. When you try to call these non-existent functions in your 'reader' executable, your code happily tries to call them but you get a segfault (or whatever error your OS gives) because that's not the start of a valid function in your 'reader' executable.
Now with regard to writing complex types (e.g. std::vector) directly to a file in binary format: Doing so "works" in the sample code above only because the binary copies of the std::vectors have pointers that, once read back in, still point to valid data from the original std::vectors which you wrote out. Note that you didn't write the std::vector's actual data, you only wrote their metadata, which probably includes things like the length of the vector, the amount of memory currently allocated for the vector, and a pointer to the vector's data. When you read that back, the metadata is correct except for one thing: Any pointers in it are pointing to addresses that were valid when you wrote the data, but which may not be valid now. In the case of the sample code above, the pointers end up pointing to the same (still valid) data from the original vectors. But there's still a problem here: You now have more than one std::vector that thinks they own that memory. When one of them is deleted, it will delete the memory that the other vector expects to still exist. And when the other vector is deleted, it will cause a double-delete. That opens the door to all kinds of UB. E.g. that memory could have been allocated for another purpose by that time, and now the 2nd delete will delete that other purpose's memory, or else the memory has NOT been allocated for another purpose and the 2nd delete may corrupt the heap. To fix this, you'd have to serialize out the essence of each vector, rather than their binary representation, and when reading it back in, you'd have to reconstruct an equivalent copy, rather than simply reconstitute a copy from the binary image of the original.
This is my second time using C++ and I'm trying to port some Java code I made but am having trouble understanding some behavior. I have a list of data and want to create another list of the same size but the values are default to zero(in Java I use Arrays.fill(list, 0); after creating it). When I try to do something similar in C++ I get variable-sized object 'list1' may not be initialized
Here's a code to better example:
#include <iostream>
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
using namespace std;
using namespace boost::assign;
int main()
{
cout << "Hello World!" << endl;
vector<short> data;
data += -40, -30,-10, 20, 50;
//int coeff [data.size()];
cout << "data array size is " << data.size() << endl;
short list1 [data.size()] = {0}; //does not work
for (int i =0; i<data.size(); i++) {
cout << "data is " << list1[i] << endl;
}
cout << "********** try 2 **************" << endl;
//this works if I use a actual number to create the list but I want to declare it at runtime
short list2 [5] = {0};
for (int ii=0;ii<5;ii++) {
cout << "data is " << list2[ii] << endl;
}
return 0;
}
Like I mentioned, I'm completely green when I comes to C++ (I have read a book and done a few tutorials) so I may be doing something completely wrong. In the event I cannot do this at runtime and only at compile time, is there something else I can use to get the same result?
c++ does not have dynamically sized arrays, so this is illegal:
short list1 [data.size()];
but you can use a vector:
std::vector<short> list1(data.size(),0);
That creates a vector of the same length as data, full of zeroes.
If you want an array whose size is determined at runtime, you'll have to allocate it.
short * list1 = new short[data.size()];
//do stuff
delete [] list1; //we don't want to leak
You typically want to avoid naked pointers whenever possible, so the cleaner solution is what juanchopanza suggested and try to use std::vector.
The equivalent of Arrays.fill(list, 0); for a C++ vector looks like std::fill(list.begin(), list.end(), 0);
You can also simply declare a std::vector<short> list1(data.size()); to create it with zero initialized values or with a specific value std::vector<short> list1(data.size(), 0);