Можно ли использовать указатели на функции между процессами? - PullRequest
7 голосов
/ 13 октября 2009

Я знаю, что каждый процесс создает свое собственное адресное пространство памяти, однако мне было интересно,

Если процесс А должен был иметь такую ​​функцию, как:

int DoStuff() { return 1; }

и указатель typedef, например:

typedef int(DoStuff_f*)();

и функция получения, например:

DoStuff_f * getDoStuff() { return DoStuff; }

и магический способ общения с процессом B через ... скажем, boost :: interprocess

Можно ли передать указатель функции в процесс B и вызвать

Процесс DoStuff A напрямую от процесса B?

Ответы [ 6 ]

8 голосов
/ 13 октября 2009

Нет. Все указатели функций - это адрес в адресном пространстве вашего процесса. У него нет внутреннего маркера, уникального для разных процессов. Таким образом, даже если ваш указатель на функцию оказался действительным после того, как вы переместили его в B, он вызвал бы эту функцию от имени процесса B.

Например, если у вас было

////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!

Если процессы A и B выполняют один и тот же код, вы можете получить одинаковые функции по одинаковым адресам, но вы все равно будете работать со структурами данных B и глобальной памятью! Итак, короткий ответ: нет, это не то, как вы хотите это сделать!

Кроме того, меры безопасности, такие как рандомизация макета адресного пространства , могут помешать такому типу "уловок".

Вы путаете IPC и RPC. IPC предназначен для передачи данных, таких как ваши объекты или большой текстовый блок. RPC предназначен для выполнения кода в удаленном процессе.

8 голосов
/ 13 октября 2009

Короче говоря, вы не можете использовать указатель на функцию, переданную другому процессу.

Коды функций находятся на защищенных страницах памяти, в них нельзя писать. И каждый процесс имеет изолированное виртуальное адресное пространство, поэтому адрес функции недопустим в другом процессе. В Windows вы можете использовать методику, описанную в этой статье , чтобы внедрить ваш код в другой процесс, но последняя версия Windows отклоняет его.

Вместо передачи указателя на функцию, вы должны рассмотреть возможность создания библиотеки, которая будет использоваться в обоих процессах. В этом случае вы можете отправить сообщение другому процессу, когда вам нужно вызвать эту функцию.

1 голос
/ 13 октября 2009

Вот почему люди изобрели такие вещи, как COM, RPC и CORBA.Каждый из них дает такую ​​общую возможность.Как вы можете догадаться, каждый выполняет эту работу немного по-другому, чем другие.

Boost IPC на самом деле не поддерживает удаленные вызовы процедур.Это позволит поместить переменную в разделяемую память, чтобы она была доступна двум процессам, но если вы хотите использовать метод получения / установки для доступа к этой переменной, вам придется сделать это самостоятельно.

Все это, по сути, обертки, которые создают «приятную» версию того, что вы можете сделать без них.В Windows, например, вы можете поместить переменную в общую память самостоятельно.Вы можете сделать то же самое в Linux.Библиотека Boost является довольно «тонкой» библиотекой, которая позволяет вам писать один и тот же код для Windows или Linux, но не пытается создавать много на ее основе.CORBA (для одного примера) - гораздо более толстый слой, обеспечивающий относительно полную распределенную среду.

1 голос
/ 13 октября 2009

Указатель функции не будет работать для этого, потому что он содержит только начальный адрес для кода; если рассматриваемый код не существует в другом процессе или (из-за чего-то вроде рандомизации адресного пространства) находится в другом месте, указатель функции будет бесполезным; во втором процессе он будет указывать на что-то или ничего, но почти наверняка не туда, куда вы хотите.

Если бы вы сошли с ума ^ Wdaring, вы могли бы скопировать фактическую последовательность команд в общую память, а затем сразу перейти к второму процессу - но даже если бы вы могли заставить это работать, функция все равно будет работать в Process B, а не Процесс A.

Звучит так, будто вы на самом деле хотите передавать сообщения или использовать RPC-систему.

1 голос
/ 13 октября 2009

Если бы вы попытались использовать указатель на функцию процесса A из процесса B, вы бы не вызывали процесс A - вы бы вызывали все, что находится по тому же адресу в процессе B. Если это одна и та же программа, вам может повезти и это будет тот же код, но у него не будет доступа ни к каким данным, содержащимся в процессе A.

0 голосов
/ 13 октября 2009

Если оба процесса находятся в одном приложении, это должно работать. Если вы пытаетесь отправить указатели функций между приложениями, вам не повезло.

Мой первоначальный ответ был верным, если вы предполагаете, что процесс и поток - это одно и то же, но это не так. Другие ответы верны - разные процессы не могут совместно использовать функциональные указатели (или любые другие указатели в этом отношении).

...