tags:

views:

442

answers:

6

I'm aware that each process creates it's own memory address space, however I was wondering,

If Process A was to have a function like :

int DoStuff() { return 1; }

and a pointer typedef like :

typedef int(DoStuff_f*)();

and a getter function like :

DoStuff_f * getDoStuff() { return DoStuff; }

and a magical way to communicate with Process B via... say boost::interprocess

would it be possible to pass the function pointer to process B and call

Process A's DoStuff from Process B directly?

A: 

If both processes are in the same application, then this should work. If you are trying to send function pointers between applications then you are out of luck.

My original answer was correct if you assume a process and a thread are the same thing, which they're not. The other answers are correct - different processes cannot share function pointers (or any other kind of pointers, for that matter).

Graeme Perrow
so in other words : even if I do use boost::interpcocess, managed shared memory segment (for example) then even if I pass the pointer - It still won't work, correct ?
Maciek
I know nothing about boost, but it doesn't matter how you communicate the pointers among processes. If your program spawns multiple threads, you can pass pointers between them. If you are starting up two separate applications, you cannot.
Graeme Perrow
Please share with us your definition of "process" versus "application."
kmarsh
Oops - I was mixing up processes and threads. My comment is correct, my answer is not. I will update.
Graeme Perrow
It's not clear what you mean by same "application". If they are in different processes, there's no guarantee any of this will work.Perhaps you meant if they are different threads in the same process? In that case, this might do what you want. But the OP indicated separate processes quite explicitly...
Steven Schlansker
+8  A: 

In short, you cannot use function pointer that passed to another process.

Codes of function are located in protected pages of memory, you cannot write to them. And each process has isolated virtual address space, so address of function is not valid in another process. In Windows you could use technique described in this article to inject your code in another process, but latest version of Windows rejects it.

Instead of passing function pointer, you should consider creating a library which will be used in both processes. In this case you could send message to another process when you need to call that function.

Kirill V. Lyadvinsky
+1  A: 

If you tried to use process A's function pointer from process B, you wouldn't be calling process A - you'd call whatever is at the same address in process B. If they are the same program you might get lucky and it will be the same code, but it won't have access to any of the data contained in process A.

Mark Ransom
+7  A: 

No. All a function pointer is is an address in your process's address space. It has no intrinsic marker that is unique to different processes. So, even if your function pointer just happened to still be valid once you've moved it over to B, it would call that function on behalf of process B.

For example, if you had

////PROCESS A////
int processA_myfun() { return 3; }
// get a pointer to pA_mf and pass it to process B

////PROCESS B////
int processB_myfun() { return 4; } // This happens to be at the same virtual address as pA_myfun
// get address from process A
int x = call_myfun(); // call via the pointer
x == 4;  // x is 4, because we called process B's version!

If process A and B are running the same code, you might end up with identical functions at identical addresses - but you'll still be working with B's data structures and global memory! So the short answer is, no, this is not how you want to do this!

Also, security measures such as address space layout randomization could prevent these sort of "tricks" from ever working.

You're confusing IPC and RPC. IPC is for communicating data, such as your objects or a blob of text. RPC is for causing code to be executed in a remote process.

Steven Schlansker
+1 for ASLR - I was trying to remember details about that.
Mark Ransom
+1  A: 

A function pointer won't work for this, because it only contains the starting address for the code; if the code in question doesn't exist in the other process, or (due to something like address space randomization) is at a different location, the function pointer will be useless; in the second process, it will point to something, or nothing, but almost certainly not where you want it to.

You could, if you were insane^Wdaring, copy the actual instruction sequence onto the shared memory and then have the second process jump directly to it - but even if you could get this to work, the function would still run in Process B, not Process A.

It sounds like what you want is actually some sort of message-passing or RPC system.

Jack Lloyd
yep message passing. Already implemented one using boost::interprocess, was wondering about "other ways"
Maciek
+1  A: 

This is why people have invented things like COM, RPC and CORBA. Each of them gives this general kind of capability. As you'd guess, each does so the job a bit differently from the others.

Boost IPC doesn't really support remote procedure calls. It will enable putting a variable in shared memory so its accessible to two processes, but if you want to use a getter/setter to access that variable, you'll have to do that yourself.

Those are all basically wrappers to produce a "palatable" version of something you can do without them though. In Windows, for example, you can put a variable in shared memory on your own. You can do the same in Linux. The Boost library is a fairly "thin" library around those, that lets you write the same code for Windows or Linux, but doesn't try to build a lot on top of that. CORBA (for one example) is a much thicker layer, providing a relatively complete distributed environment.

Jerry Coffin