首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在带有Inline::C的Perl中使用VTD-XML?

如何在带有Inline::C的Perl中使用VTD-XML?
EN

Stack Overflow用户
提问于 2011-06-08 17:21:10
回答 1查看 224关注 0票数 2

我最近发现了VTD-XML解析XML方法的强大功能,主要是它的速度。具体来说,我已经构建了C版本2.10 (也有Java、C++和C#实现)。

我的目标很简单:我想使用VTD-XML从XML中提取数据进行解析,并使用Perl处理数据。最简单的方法可能是用我编写的C程序转储数据,然后通过管道将它们发送到Perl程序。也许不是很优雅,但它是有效的。

另一种不太容易的方法是由一个Perl程序组成,该程序使用Inline::C调用C数据收集子例程。

因此,我开始学习Inline::C,并设法完成了使用Perl C API函数将数据从C子例程传递回Perl所需的基本操作。当我在C源代码中的Inline::C控制下编写C收集器子例程时,在编译阶段出现了问题。

有这样的符号冲突: bind()在socket.h ( Perl )和autoPilot.h ( VTD-XML )中定义。可以避免符号冲突,将VTD-XML构建为具有显式导出映射( gcc -Wl,-版本脚本=foo.map)的共享库...这条路对吗?有没有更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-09 22:40:51

我确实通过添加一层间接层达到了我的目标:糟糕,因为它在我看来是有效的。

首先,我创建了一个包含VTD-XML API的共享库。构建这个共享对象时,我必须避免全局作用域污染,只导出需要的符号。

然后我构建了另一个共享库。第二个共享的libray隐藏了VTD-XML,并且应该通过Inline::C在Perl中使用。在这个共享对象中,我使用libvtd.so部分公开的API编写了一些函数。

这个想法看起来像这样:

代码语言:javascript
复制
Perl -> Inline::C dynamic loader -> wrapper_API.so -> libvtd.so 

主要问题来自于共享库的运行时加载和符号冲突/解决。

下面是我如何构建libvtd.so,以方便所谓的wrapper_API.so使用它。

不幸的是,VTD-XML不能构建libvtd.so共享对象,所以我不得不自己构建它,并与gcc将几个.o对象文件链接在一起:

代码语言:javascript
复制
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调整了符号可见性,其中映射文件为:

代码语言:javascript
复制
{
    global:
        the_exception_context;
        toString;
        getText;
        getCurrentIndex;
        toNormalizedString;
        toElement;
        toElement2;
        createVTDGen;
        setDoc;    
        parse;
        getNav;
        freeVTDGen;
        freeVTDNav;
        getTokenCount;
    local:
        *;  
};

全局(“导出”)符号在global:部分下,而本地下的catchall *表示所有其他符号仅在本地已知。

所有的对象模块都来自VTD-XML发行版,除了libvtd.o:需要这个自定义对象来解决异常处理库cexept.h的问题。libvtd.c只有两行代码。

代码语言:javascript
复制
#include "customTypes.h"
struct exception_context the_exception_context[ 1 ];

在编译阶段,我不得不调整的CFLAGS使位置独立的代码( gcc -fPIC选项),以便使共享对象。

readelf工具对检查符号可见性很有用:

readelf --syms libvtd.so.2.10

代码语言:javascript
复制
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由几个函数组成,这些函数使用VTD-XML及其自定义类型,但只接受和返回标准的C类型和/或结构。包装器直接来自以前的独立C程序。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6276626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档