3

I am using libxml2 in a tweak, but I get a symbol redefinition error. Looks like some DataAccess-structs.h from theos uses the same xmlNode struct similar to libxml. Since, both of these are shared libraries that maybe used by other applications, I am not sure how to solve it without breaking everything.

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk/usr/include/libxml2/libxml/tree.h:488:8: error: 
      redefinition of '_xmlNode'
struct _xmlNode {
       ^
<User_home>/Documents/substrate/theos/include/DataAccess/DataAccess-Structs.h:16:16: note: 
      previous definition is here
typedef struct _xmlNode {
Antony Thomas
  • 3,576
  • 2
  • 34
  • 40

1 Answers1

0

So I went through some options posted in SO and figured that dynamically loading the library at runtime is the better of the evils. using objcopy or trying to relink as static library is not good given that these are shared libraries across many applications.

The fundamental idea is to use dlopen, dlsym and dlclose to accomplish the task. However, the problem is not just in linking but also in compilation. To solve the compilation problem you have two options
a) Use #define to redefine the symbol name as shown here.
b) Use abstract pointers (void*) and totally avoid all the xml structures.

Option (a) has a drawback in that you have to redefine every colliding symbol of libxml2 and theos whereas Option (b) may lead to incorrect cast by using void* or xml structs.

I chose option (b) and is how you do it if you did the same

Create a list of typedef for the xmlElements that you want to use. I was using libxml as a writer and hence I typdef all the writer structures.

typedef void* (*xmlNewTextWriterFilenameFPtr)(const char *uri, int compression);
typedef int (*xmlTextWriterStartDocumentFPtr)(void *writer,const char *version,const char *encoding,const char *standalone);
typedef int (*xmlTextWriterEndDocumentFPtr)(void *writer);

Then for every method that you have to call use dlopen and dlsym.

void *lib=dlopen(path_to_libxml,RTLD_LOCAL);
const char *func_xmlNewTextWriterFilename = "xmlNewTextWriterFilename";
if(lib == NULL){printf("%s","Problem loading library");} 
xmlNewTextWriterFilenamePtr fptrWriter=(xmlNewTextWriterFilenamePtr)dlsym(lib, func_xmlNewTextWriterFilename);
void *writer=fptrWriter(OUT_FILE_PATH,0);
Community
  • 1
  • 1
Antony Thomas
  • 3,576
  • 2
  • 34
  • 40