Is it possible to use function pointers across processes?

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?

13.10.2009 17:08:50
Please state the O/S you are dealing with. The answer to the question is very different for vxWorks versus Linux.
kmarsh 13.10.2009 17:22:40
Agreed - all the "no" answers should be understood as "not portably", and/or "not on my OS". On some platforms with very lightweight OSes there is no protected memory, and it will just work.
Steve Jessop 13.10.2009 17:44:47
I suppose it is Windows. My assumption based on early Maciek's questions and style of function naming :)
Kirill V. Lyadvinsky 13.10.2009 18:04:18
@onebyone: Basically if you are running on SOC with no virtual address space it may be potentially possable.
Martin York 13.10.2009 18:42:51
6 ОТВЕТОВ
РЕШЕНИЕ

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.

8
13.10.2009 17:23:20

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).

0
13.10.2009 17:27:31
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 13.10.2009 17:13:46
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 13.10.2009 17:17:03
Please share with us your definition of "process" versus "application."
kmarsh 13.10.2009 17:23:26
Oops - I was mixing up processes and threads. My comment is correct, my answer is not. I will update.
Graeme Perrow 13.10.2009 17:26:03
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 13.10.2009 17:26:38

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.

8
13.10.2009 17:33:31

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.

1
13.10.2009 17:22:44

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.

1
13.10.2009 17:23:34
yep message passing. Already implemented one using boost::interprocess, was wondering about "other ways"
Maciek 13.10.2009 19:01:06

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.

1
13.10.2009 17:39:57