Я достиг своей цели, добавив слой косвенности: ужасно, как мне кажется, это работает.
Прежде всего, я создал общую библиотеку, содержащую API VTD-XML.Создавая этот общий объект, я должен был избежать загрязнения глобальной области видимости, экспортируя только необходимые символы.
Затем я создал другую общую библиотеку.Эта вторая общая библиотека скрывает API VTD-XML и должна использоваться из Perl через Inline :: C.В этом общем объекте я написал несколько функций, используя частично выставленный API libvtd.so.
Идея выглядит следующим образом:
Perl -> Inline::C dynamic loader -> wrapper_API.so -> libvtd.so
Основные проблемы возникли из-за загрузки общих библиотек во время выполнения ииз столкновения / разрешения символов.
Вот как я собираю libvtd.so, упрощая использование так называемого wrapper_API.so.
К сожалению, VTD-XML не собираетсяlibvtd.so
общий объект, поэтому мне пришлось создать его самостоятельно, связав вместе несколько объектных файлов .o с помощью gcc:
gcc -shared -fPIC -Wl,-soname,libvtd.so.2.10 -Wl,--version-script=vtd-xml.map \
-o libvtd.so.2.10 libvtd.o arrayList.o fastIntBuffer.o fastLongBuffer.o \
contextBuffer.o vtdNav.o vtdGen.o autoPilot.o XMLChar.o XMLModifier.o intHash.o \
bookMark.o indexHandler.o transcoder.o elementFragmentNs.o
Видимость символа была настроена с помощью опции компоновщика -Wl,--version-script=vtd-xml.map
, где файл карты был:
{
global:
the_exception_context;
toString;
getText;
getCurrentIndex;
toNormalizedString;
toElement;
toElement2;
createVTDGen;
setDoc;
parse;
getNav;
freeVTDGen;
freeVTDNav;
getTokenCount;
local:
*;
};
Глобальные ("экспортированные") символы находятся в разделе global:
, в то время как универсальный символ *
в разделе local говорит о том, что все остальные символы известны только локально.
Все объектные модули происходят из дистрибутива VTD-XML, за исключением libvtd.o: этот пользовательский объект был необходим для решения проблем с библиотекой обработки исключений cexept.h.libvtd.c - это всего две строки кода.
#include "customTypes.h"
struct exception_context the_exception_context[ 1 ];
На этапе компиляции мне пришлось настроить CFLAGS для создания независимого от позиции кода (опция gcc -fPIC
) для создания общих объектов. *Инструмент 1030 *
readelf был полезен для проверки видимости символов:
readelf --syms libvtd.so.2.10
Symbol table '.dynsym' contains 35 entries:
Num: Value Size Type Bind Vis Ndx Name
...
280: 000000000000d010 117 FUNC LOCAL DEFAULT 12 writeIndex
281: 000000000003c5d0 154 FUNC LOCAL DEFAULT 12 setCursorPosition
282: 000000000003c1f0 56 FUNC LOCAL DEFAULT 12 resetIntHash
...
331: 0000000000004f50 3545 FUNC GLOBAL DEFAULT 12 toElement
332: 00000000000071e0 224 FUNC GLOBAL DEFAULT 12 getText
333: 000000000000d420 114 FUNC GLOBAL DEFAULT 12 freeVTDGen
...
339: 000000000000b600 731 FUNC GLOBAL DEFAULT 12 toElement2
340: 000000000000e650 120 FUNC GLOBAL DEFAULT 12 getNav
341: 0000000000025750 70567 FUNC GLOBAL DEFAULT 12 parse
Файл wrapperAPI.so состоит из нескольких функций, использующих API VTD-XML, его пользовательские типы., но принимать и возвращать только стандартные типы C и / или структуры.Оболочка пришла прямо из бывшей отдельной программы на Си.