3

使用 iOS 7 SDK 时,由于libxml2中的更改,我不得不更改库的单行以对 xmloutput 缓冲区使用新的输出缓冲区访问器方法。

NSData * result = [[[NSData alloc] initWithBytes:outputBuffer->buffer->content 
                                  length:outputBuffer->buffer->use] autorelease];

导致编译错误“struct_xmlBuf 类型的定义不完整”。使用新的访问器方法,这变成了:

NSData * result = [[NSData alloc] initWithBytes:xmlOutputBufferGetContent(outputBuffer)
                                  length:xmlOutputBufferGetSize(outputBuffer)];

这工作正常,但是当在 iOS 6 上运行时,对于提到 libxml2.2.dylib 的新方法,它会因“惰性符号绑定失败:未找到符号”而崩溃,这并不奇怪。

您如何有条件地进行此更改,以使用基本 SDK iOS 7 编译并仍可在 iOS 5、6 和 7 上运行?

注意:通常在运行时检查 iOS 版本和其他问题一样是不够的,因为旧行不再编译。

我一直在尝试和考虑:

  • 检查xmlOutputBufferGetContent != NULL,总是正确的
  • 使用 libxml2.2 而不是 libxml2
  • 检查LIBXML_DOTTED_VERSION,总是 2.9.0
  • 检查LIBXML2_NEW_BUFFER定义的新方法,始终为真

所有这些导致在编译之前或之后总是只选择一行,主要基于 SDK。在非 iOS 项目(谷歌搜索)中处理这种变化的其他少数人似乎总是针对一个版本的 libxml 进行编译。

4

1 回答 1

1

像下面这样的东西应该工作:

#include <dlfcn.h>

typedef const xmlChar *(*getContent_t)(xmlOutputBufferPtr out);
typedef size_t (*getSize_t)(xmlOutputBufferPtr out);

然后:

int libxmlVersion = atoi(xmlParserVersion);

if (libxmlVersion < 20900) {
    xmlBufferPtr oldStyleBuffer = (xmlBufferPtr)outputBuffer->buffer;
    NSData * result = [[[NSData alloc] initWithBytes:oldStyleBuffer->content 
                              length:oldStyleBuffer->use] autorelease];
}
else {
    getContent_t getContent = dlsym(RTLD_DEFAULT, "xmlOutputBufferGetContent");
    getSize_t getSize = dlsym(RTLD_DEFAULT, "xmlOutputBufferGetSize");
    NSData * result = [[NSData alloc] initWithBytes:getContent(outputBuffer)
                              length:getSize(outputBuffer)];
}

对于旧版本的 libxml2(2.9.0 之前),使用旧的缓冲区结构。对于较新的版本,使用 搜索新的访问器dlsym。缓存返回的函数指针dlsym将提高性能。

于 2013-09-20T21:35:41.723 回答