2013-02-11 74 views
5

मेरे पास एक सी ++ प्रोग्राम है जिसमें एक खाली xlsx फ़ाइल पर बाहरी निर्भरता शामिल है। इस निर्भरता को निकालने के लिए मैं सीधे उस में जोड़ने, का उपयोग करते हुए ध्यान में रखते हुए एक द्विआधारी वस्तु के लिए इस फ़ाइल को परिवर्तित:डेटा फ़ाइल का एलडी डेटा का आकार * एबीएस * बनाता है और एक पूर्णांक नहीं

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

objdump का उपयोग करना द्वारा

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

पीछा किया, मैं देख सकता हूँ तीन चर की घोषणा की:

$ 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 

मैं तो इस डेटा के बारे में मेरे कार्यक्रम बता:

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 

यह संकलित करता है तथा ठीक लिंक, (हालांकि मैं कुछ परेशानी cmake साथ यह स्वचालित चल रहा है, यहाँ देखें: compile and add object file from binary with cmake)

हालांकि, जब मैं अपने कोड में _binary_template_xlsx_size उपयोग करें, यह एक पते के सूचक के रूप में समझा जाता है कि अस्तित्व में नहीं है तो मेरी डेटा का आकार प्राप्त करने के लिए, मैं (int)&_binary_template_xlsx_size (या (int)(_binary_template_xlsx_end - _binary_template_xlsx_start)) पारित करने के लिए

कुछ शोध मुझसे कहता है कि objdump में *ABS* ऊपर "निरपेक्ष मूल्य" का अर्थ है, लेकिन मैं क्यों नहीं मिलता है। वैरिएबल को int के रूप में देखने के लिए और पॉइंटर के रूप में नहीं देखने के लिए मैं अपना सी ++ (या सी) प्रोग्राम कैसे प्राप्त कर सकता हूं?

+0

मैं क्यों या कैसे इस से बचने के लिए के रूप में दस्तावेज में कुछ संकेत हो सकता है लगता है: सुनिश्चित करें कि आप एक int के रूप में यह प्रयोग कर रहे हैं, तो आप मैक्रो का उपयोग कर सकते हैं। फ़ाइल को एक समावेशी सरणी परिभाषा में बदलने के लिए केवल एक साधारण स्क्रिप्ट क्यों न लिखें? –

+0

फ़ाइल एक xlsx फ़ाइल है: xml फ़ाइलों का एक ज़िप संग्रह। कारण मैंने ऐसा इसलिए किया क्योंकि मैंने कोड को अनजिप करने के लिए कोड लिखने में कुछ समय बिताया, फाइलों के माध्यम से पुनरावृत्त किया, और एक्सएमएल पार्स किया, और मैं वह सब फिर से नहीं करना चाहता। इसके अलावा यह मजेदार है। –

+0

इसके अलावा मैं डेटा को ठीक से एक्सेस कर सकता हूं। मैं यह पता लगाने की कोशिश कर रहा हूं कि यहां क्या हो रहा है, क्योंकि मैं इस व्यवहार से चिंतित हूं। –

उत्तर

3

एक *ABS* प्रतीक एक पूर्ण पता है; यह अक्सर --defsym foo=0x1234 को एलडी में पास करके बनाया जाता है।

--defsym symbol=expression 

आउटपुट फ़ाइल में एक वैश्विक प्रतीक बनाएँ, पूर्ण पता अभिव्यक्ति द्वारा दिए गए हैं। [...]

क्योंकि एक पूर्ण प्रतीक स्थिर है, इसलिए इसे एक सी स्रोत फ़ाइल में एक चर के रूप में लिंक करना संभव नहीं है; सभी सी ऑब्जेक्ट चर के पास एक पता है, लेकिन स्थिर नहीं है। आप बनाना चाहते हैं

extern const char _binary_template_xlsx_size[]; 

:

सुनिश्चित करें कि आप पता भिन्नता न हो जाए दुर्घटना से (यानी चर पढ़ें), यह आप के रूप में const char [] के रूप में यह परिभाषित करने के लिए अन्य प्रतीकों के साथ सबसे अच्छा है

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)