2012-06-03 22 views
11

एलएलवीएम में stdin, stout, और stderr (अधिमानतः सी संस्करण) कैसे घोषित करता है? मैं एक खिलौना भाषा में कुछ stdio कार्यों का उपयोग करने की कोशिश कर रहा हूँ मैं बना रहा हूँ।एलएलवीएम stdin/stdout/stderr

char * fgets (char * str, int num, FILE * stream); 

आदेश उपयोग करने के लिए है कि मैं stdin जरूरत में: ऐसा ही एक समारोह fgets था। इसलिए मैंने पाया कि FILE की परिभाषा उत्पन्न करने के लिए कुछ एलएलवीएम एपीआई कोड लिखा है, और stdin बाहरी वैश्विक घोषित किया है। कोड इस उत्पन्न:

%file = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %marker*, %file*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] } 
%marker = type { %marker*, %file*, i32 } 

@stdin = external global %file* 

हालांकि, जब मैं जिसके परिणामस्वरूप मॉड्यूल भाग गया, यह मुझे इस त्रुटि दिया:

Undefined symbols for architecture x86_64: 
"_stdin", referenced from: 
    _main in cc9A5m3z.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 

जाहिर है, क्या मैंने लिखा काम नहीं किया। तो मेरा सवाल यह है कि मुझे stdin, stout, और stderr घोषित करने के लिए एलएलवीएम एपीआई में fgets जैसे खिलौने भाषा कंपाइलर की तरह कुछ करने के लिए मुझे क्या लिखना है?

+0

आप सी में सहायक कार्यों को लिख सकते हैं जो stdin/stdout/stderr को वापस कर देंगे और उन्हें आपके प्रोग्राम से लिंक करेंगे। –

+0

मैं इसे आज़माउंगा, हालांकि अगर मैं कर सकता हूं तो एलएलवीएम एपीआई हमें ऐसा करने की अनुमति देता है, अगर मैं कर सकता हूं। – tophat

उत्तर

6

यदि कोई दिलचस्पी है, तो मुझे अपने प्रश्न का उत्तर मिला। कुछ गहन खोज के बाद मुझे सी 12 एक्सटेंशन बनाने के बिना stdin स्ट्रीम प्राप्त करने का कोई तरीका मिला: fdopen और FILE एक अपारदर्शी संरचना बना रहा।

FILE* fdopen (int fildes, const char *mode) 

जब fdopen एक फ़ाइल वर्णनकर्ता (fildes) के लिए 0 पारित हो जाता है यह stdin धारा देता है। LLVM एपीआई का उपयोग करना, मैं निम्नलिखित LLVM विधानसभा उत्पन्न:

%FILE = type opaque 
declare %FILE* @fdopen(i32, i8*) 
@r = constant [2 x i8] c"r\00" 

तब मैं इस कॉल के बयान के साथ stdin पुनः प्राप्त करने में सक्षम था:

%stdin = call %FILE* @fdopen(i32 0, i8* getelementptr inbounds ([2 x i8]* @r, i32 0, i32 0)) 
1

यह मंच विशिष्ट है। कभी-कभी stdin विभिन्न प्रतीक नाम के लिए मैक्रो है।

एंड्रॉइड पर, उदाहरण के लिए, stdin #define stdin (&__sF[0]) है।

माइक्रोसॉफ्ट विज़ुअल सी ++ के लिए, stdin #define stdin (&__iob_func()[0])

तो तुम सच में अपने मंच stdio.h हैडर में देखना है कि यह पता लगाने की जरूरत है।

+0

तो, मुझे stdin घोषित करने के लिए एलएलवीएम एपीआई में लिखने की क्या ज़रूरत है, उदाहरण के लिए, खिलौना भाषा संकलक? – tophat

+0

आपको stdio के लिए उपयोग करने के लिए प्रतीक/घोषणा का पता लगाने के लिए 'stdio.h' शीर्षलेख से अपने प्लेटफॉर्म को देखने की आवश्यकता है, इसलिए यह आपके द्वारा उपयोग की जाने वाली सी रनटाइम लाइब्रेरी के साथ सही ढंग से लिंक करता है। –

5

आप putchar जैसे कार्यों का उपयोग करते हैं, printf, gets, strtol , puts, fflush आपको stdin और stdout की आवश्यकता नहीं होगी। मैंने एक खिलौना कंपाइलर लिखा और वे तारों और पूर्णांक के साथ I/O के लिए पर्याप्त थे। fflush को शून्य के साथ बुलाया जाता है और stdout फ़्लश हो जाता है।

%struct._IO_FILE = type opaque 
declare i32 @fflush(%struct._IO_FILE*) 
... 
call i32 @fflush(%struct._IO_FILE* null) 
... 
संबंधित मुद्दे