Reputation: 365
The problem i have is that i don't know how to do the casting properly, my objective is to call the method that will be placed in the buf.
This is my compiler error.
error: ‘buf’ cannot be used as a function
This is my current code
...
unsigned char *getFileBuffer(const char filename[], long &fileSize)
{
...
}
void (*ptrox)(int &) = NULL;
int main()
{
long filesize = -1;
int x = 3;
//buf will consist of a operation, that takes an referenced int as an argument.
unsigned char *buf = getFileBuffer("foo", filesize);
//This is obviously not correct and does not match the description.
ptrox = (void *)&buf(int &);
ptrox(x);
cout << x;
}
And this is the actual method / buffer.
void i(int &x)
{
x += 2;
}
__Z1iRi:
0000000100000cbb 55 pushq %rbp
0000000100000cbc 4889e5 movq %rsp, %rbp
0000000100000cbf 48897df8 movq %rdi, -0x8(%rbp)
0000000100000cc3 488b45f8 movq -0x8(%rbp), %rax
0000000100000cc7 8b00 movl (%rax), %eax
0000000100000cc9 8d5002 leal 0x2(%rax), %edx
0000000100000ccc 488b45f8 movq -0x8(%rbp), %rax
0000000100000cd0 8910 movl %edx, (%rax)
0000000100000cd2 5d popq %rbp
0000000100000cd3 c3 ret
Upvotes: 0
Views: 869
Reputation: 22542
A correct typecast would look like this:
ptrox = (void (*)(int &))buf;
Why don't you use dlopen
/dlsym
for loading functions? Will be less error prone. Also by default your memory into which you load your function will not be executable, so if you try to run ptrox
it will get a SIGSEGV
.
In order to use libdl
you would need to compile your function foo
for example in a shared library and load it like this:
void * libhandle = dlopen("foo.so", RTLD_NOW);
if (!libhandle) {
perror("dlopen");
abort();
}
ptrox = (void (*)(int &))dlsym(libhandle,
"foo" // C function name (use extern "C" where appropriate)
);
if (!ptrox) {
perror("dlsym");
abort();
}
If you require to load a C++ function pointer to be loaded then you will need to use it's mangled function name. Consult nm foo.so
for it.
How to mmap
executable memory:
void * getFileBuffer(const char filename[], long fileSize) {
int fd = open(filename, O_RDONLY);
if (fd < 0) {
perror("open");
abort();
}
void * buf = mmap(
NULL
, fileSize
, PROT_READ | PROT_EXEC
, MAP_PRIVATE
, fd
, 0
);
if (buf == MAP_FAILED) {
perror("map");
abort();
}
return buf;
}
Upvotes: 2
Reputation: 439
For me the following construct works:
ptrox = (void (*)(int &))buf;
but don't know why the paranthesis around * is needed.
how i usually handle this:
typedef void *pfunc(int &);
then i can use
ptrox = (pfunc)buf;
Upvotes: 0