2013-02-11 10 views
5

Ho un programma C++ che include una dipendenza esterna su un file xlsx vuoto. Per rimuovere questa dipendenza ho convertito il file a un oggetto binario in vista del collegamento in diretta, utilizzando:ld del file di dati rende la dimensione dei dati un * ABS * e non un intero

ld -r -b binary -o template.o template.xlsx 

seguito da

objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents template.o template.o 

Utilizzando objdump, posso vedere tre variabili dichiarate:

$ objdump -x template.o 

template.o:  file format elf64-x86-64 
template.o 
architecture: i386:x86-64, flags 0x00000010: 
HAS_SYMS 
start address 0x0000000000000000 

Sections: 
Idx Name   Size  VMA    LMA    File off Algn 
    0 .rodata  00000fd1 0000000000000000 0000000000000000 00000040 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
SYMBOL TABLE: 
0000000000000000 l d .rodata  0000000000000000 .rodata 
0000000000000fd1 g  *ABS* 0000000000000000 _binary_template_xlsx_size 
0000000000000000 g  .rodata  0000000000000000 _binary_template_xlsx_start 
0000000000000fd1 g  .rodata  0000000000000000 _binary_template_xlsx_end 

ho poi dico il mio programma su questi dati:

template.h: 
#ifndef TEMPLATE_H 
#define TEMPLATE_H 

#include <cstddef> 
extern "C" { 
    extern const char _binary_template_xlsx_start[]; 
    extern const char _binary_template_xlsx_end[]; 
    extern const int _binary_template_xlsx_size; 
} 
#endif 

Questo compila e collega bene, (anche se sto avendo qualche problema automatizzando con CMake, vedere qui: compile and add object file from binary with cmake)

Tuttavia, quando uso _binary_template_xlsx_size nel mio codice, viene interpretato come un puntatore a un indirizzo che non esiste Quindi, per ottenere la dimensione dei miei dati, devo passare (int)&_binary_template_xlsx_size (o (int)(_binary_template_xlsx_end - _binary_template_xlsx_start))

Alcune ricerche mi dice che il *ABS* nella objdump sopra significa "valore assoluto", ma io non capisco perché. Come posso ottenere il mio programma C++ (o c) per vedere la variabile come int e non come puntatore?

+0

Penso che ci possono essere alcuni suggerimenti nella documentazione sul perché o il modo per evitare questo. Perché non scrivere semplicemente un semplice script per convertire il file in una definizione di array includibile? –

+0

Il file è un file xlsx: una raccolta zippata di file xml. La ragione per cui l'ho fatto è perché ho passato un po 'di tempo a scrivere il codice per decomprimere, scorrere i file e analizzare l'xml, e non voglio rifarlo tutto. Inoltre questo è divertente. –

+0

Anche io posso accedere ai dati bene. Sto cercando di scoprire cosa sta succedendo qui, perché sono affascinato da questo comportamento. –

risposta

3

Un simbolo *ABS* è un indirizzo assoluto; è più spesso creato passando da --defsym foo=0x1234 a ld.

--defsym symbol=expression 

creare un simbolo globale nel file di output, che contiene l'indirizzo assoluto data dalla espressione. [...]

Poiché un simbolo assoluto è una costante, non è possibile collegarlo in un file di origine C come variabile; tutte le variabili oggetto C hanno un indirizzo, ma una costante no.

per essere sicuri di non fare dereference l'indirizzo (cioè leggere la variabile) per caso, è meglio definirlo come const char [] come avete con gli altri simboli:

extern const char _binary_template_xlsx_size[]; 

Se si vuole fare che si sta utilizzando come un int, è possibile utilizzare una macro:

extern const char _abs_binary_template_xlsx_size[] asm("_binary_template_xlsx_size"); 
    #define _binary_template_xlsx_size ((int) (intptr_t) _abs_binary_template_xlsx_size) 
Problemi correlati