2010-05-15 2 views
2

У меня есть сервер и клиент, написанный на C. Я пытаюсь загрузить общую библиотеку на сервере, а затем передать клиенту указатели на библиотеку. Таким образом, я могу изменить библиотеку, не компилируя ее.Можно ли загружать общую библиотеку в общую память?

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

+0

Сервер и клиент работают на одной машине? – crazyscot

+0

Да, сервер и клиент работают на одном компьютере. Сервер читает xml-файл и возвращает имена функций библиотеки в зависимости от запроса xml. Клиент читает имена функций и пытается получить указатели на библиотечные функции для их выполнения. – quimm2003

+0

Я не хочу связывать библиотеку с клиентом, потому что я хочу иметь возможность изменять функциональность без необходимости компиляции клиента. И я не хочу (если возможно) dlopen библиотеки на клиенте, потому что клиент будет вызываться много раз. – quimm2003

ответ

4

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

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

+0

Да, ты прав. Итак, я распакую библиотеку на сервере, передаю имена функций клиенту. От клиента я использую dlopen в той же библиотеке имен (которая уже открыта) и dlsym, чтобы получить указатели на функции для выполнения своего кода. Но по словам человека dlopen, это должно было дать мне тот же дескриптор как на клиенте, так и на сервере, и я получил: 0x970b0d0 для сервера и 0x89d2a38 для клиента. Означает ли это, что библиотека была загружена два раза? – quimm2003

+2

У вас есть виртуальные адреса, относящиеся к адресным пространствам процессов сервера и клиента, но они должны отображаться на один и тот же физический адрес. – qrdl

+0

@qrdl: Есть ли способ проверить это? – qdii

0

Возможно, вы могли бы, если ОС не вызывать создание совместно используемой памяти проблемы с безопасностью (что, вероятно, должно быть).

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