डी

2011-09-20 12 views
18

में सी एपीआई लागू करना तो डी के भीतर से सी एपीआई को कॉल करने के बारे में बहुत सारी जानकारी है, लेकिन रिवर्स के बारे में कैसे? डी में लाइब्रेरी लिखने के लिए आपको क्या करना है जो सामान्य सी साझा लाइब्रेरी की तरह काम करता है?डी

main.c

extern int foo(int x); 
void main() { 
    printf("foo(5)=%d\n",foo(5)); 
} 

foo.d

extern(C) 
{ 
    int foo(int x) 
    { 
     return x*x; 
    } 
} 

भोलेपन का निर्माण और जीसीसी और डीएमडी सिर्फ लिंकर त्रुटियों में परिणाम के साथ इन लिंक करने का प्रयास: यहाँ एक आसान मामला है। डिफ़ॉल्ट के लिए इस्तेमाल किया लिंकेज

/usr/lib64/libphobos2.a(deh2_2eb_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable': 
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xa): undefined reference to `_deh_beg' 
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x14): undefined reference to `_deh_beg' 
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x1e): undefined reference to `_deh_end' 
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x46): undefined reference to `_deh_end' 
/usr/lib64/libphobos2.a(lifetime.o): In function `_D2rt8lifetime18_sharedStaticCtor9FZv': 
src/rt/lifetime.d:(.text._D2rt8lifetime18_sharedStaticCtor9FZv+0x15): undefined reference to `_tlsend' 
src/rt/lifetime.d:(.text._D2rt8lifetime18_sharedStaticCtor9FZv+0x29): undefined reference to `_tlsstart' 
/usr/lib64/libphobos2.a(thread_a3_258.o): In function `_D4core6thread6Thread6__ctorMFPFZvmZC4core6thread6Thread': 
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFPFZvmZC4core6thread6Thread+0x2b): undefined reference to `_tlsend' 
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFPFZvmZC4core6thread6Thread+0x36): undefined reference to `_tlsstart' 
/usr/lib64/libphobos2.a(thread_a3_258.o): In function `_D4core6thread6Thread6__ctorMFDFZvmZC4core6thread6Thread': 
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFDFZvmZC4core6thread6Thread+0x28): undefined reference to `_tlsend' 
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFDFZvmZC4core6thread6Thread+0x33): undefined reference to `_tlsstart' 
/usr/lib64/libphobos2.a(thread_a3_258.o): In function `_D4core6thread6Thread6__ctorMFZC4core6thread6Thread': 
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFZC4core6thread6Thread+0x26): undefined reference to `_tlsend' 
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFZC4core6thread6Thread+0x31): undefined reference to `_tlsstart' 
/usr/lib64/libphobos2.a(thread_a0_713.o): In function `thread_entryPoint': 
src/core/thread.d:(.text.thread_entryPoint+0x36): undefined reference to `_tlsend' 
src/core/thread.d:(.text.thread_entryPoint+0x41): undefined reference to `_tlsstart' 
collect2: ld returned 1 exit status 
--- errorlevel 1 
+2

उम, हमें 'लटका मत छोड़ो ... त्रुटियों क्या हैं? – Mehrdad

+0

लिंकर त्रुटियां हैं: 'foo.o: फ़ंक्शन' नो प्रतीक ': foo.d :(। टेक्स्ट + 0x7):' _Dmodule_ref'' –

उत्तर

9

मेरा जवाब से डी स्थिर पुस्तकालयों का उपयोग कर सी बारे में है। हां, यह थोड़ा सा विषय है, लेकिन विंडोज के लिए साझा पुस्तकालयों का वर्णन डी के दस्तावेज (http://www.d-programming-language.org/dll.html) में किया गया है और लिनक्स अभी भी निर्माणाधीन हैं (http://www.digitalmars.com/d/2.0/changelog.html)। दोनों प्रणालियों के लिए कार्य उदाहरण संलग्न हैं।

  • Win32: डीएमडी + DMC अच्छा काम करता है। उदाहरण: test_d_from_c_win32.zip

  • Linux32: डीएमडी कुछ आवश्यक सामान एक बार यह डी मुख्य कार्य मिल गया है, तो D के मुख्य जरूरत है (dmd2 + Linux32 पर जीसीसी के लिए परीक्षण) कहते हैं। यह लिंकेज नाम "_Dmain" है और इसे सी के एक (वास्तविक "मुख्य") के साथ मिश्रित नहीं किया जाएगा। तो कोई भी dfakemain.d फ़ाइल void main(){} के साथ फ़ाइल जोड़ सकता है। dmd -c dfakemain.d गायब प्रतीकों के साथ dfakemain.o बनाएगा। इसे अपनी ऑब्जेक्ट फाइलों से लिंक करें और आप खुश होंगे।उदाहरण: test_d_from_c_linux32.tar.gz

+1

हम्म लिनक्स विधि मेरे लिए काम करती है, लेकिन इसमें अभी भी कुछ समस्याएं हैं। एक ऐसा है कि आपको अपने लिंकर के रूप में डीएमडी का उपयोग करने की आवश्यकता है। क्या कोई पुस्तकालय है जिसे आप उस मुद्दे को हल करने के लिए लिंक कर सकते हैं? दूसरा, ऐसा लगता है कि नकली मुख्य में चिपकने वाला पुस्तकालय लाइब्रेरी को डी लाइब्रेरी का उपयोग करने योग्य नहीं बनाता है, और संभवतः अन्य पुस्तकालयों के साथ असंगत है जो एक ही चाल का उपयोग कर रहे हैं। – sholte

+0

नहीं, यह आपके लिंकर_ के रूप में उपयोग किए गए डीएमडी के लिए आपको अनुरोध नहीं करता है (और ऐसा नहीं हो सकता है, क्योंकि डीएमडी लिंक नहीं कर सकता है, यह सिर्फ बाहरी लिंकर को करने के लिए कहता है)। आपको बस 'dfakemain.o' से लिंक करने की आवश्यकता है। मेरे लिनक्स उदाहरण में जीसीसी को "लिंकर के कॉलर" के रूप में उपयोग किया जाता है। _ क्या वहां कुछ लाइब्रेरी है जिसे आप उस समस्या को हल करने के लिए लिंक कर सकते हैं? _ हां। यह 'dfakemain.o' है। उदाहरण में, यह डी लाइब्रेरी (dlibrary.o) से जुड़ा नहीं है और यह नहीं होना चाहिए। इसे निष्पादन योग्य प्रति बार एक बार जोड़ा जाना चाहिए यदि यह कुछ डी पुस्तकालयों का उपयोग करता है। – Denis

+0

आह, मुझे लगता है कि मेरा जवाब वास्तव में आपके उदाहरण के build.sh में था। मैं आपके समाधान के -lrt -lphobos2 -lpthread -lm भाग खो रहा था। – sholte

6

जीसीसी सी के रूप में संकलन है, तो ++:

जीसीसी main.o foo.o के साथ लिंक करें:

doFoo.o: In function `no symbol': 
doFoo.d:(.text+0x7): undefined reference to `_Dmodule_ref' 
collect2: ld returned 1 exit status 

डीएमडी main.o foo.o के साथ लिंक करें बाहरी सी ++ होगा, सी नहीं। इसके बजाय इसे आजमाएं:

extern "C" int foo(int x); 

आपके डी वाक्यविन्यास में कुछ भी गलत नहीं लगता है। यहां आपके दृष्टिकोण की पुष्टि करने वाला अनुच्छेद है: http://www.digitalmars.com/d/2.0/interfaceToC.html

+1

को अपरिभाषित संदर्भ, सी ++ के रूप में संकलित नहीं है। बस सादा पुराना gcc -c main.c – sholte

9

compiler source code पर त्वरित नज़र के अनुसार, _Dmodule_ref मॉड्यूल कन्स्ट्रक्टर की लिंक की गई सूची है। इस मुद्दे को ठीक करने के लिए, अपने main.c से जोड़ें:

void* _Dmodule_ref; 

कार्यक्रम अब लिंक और ठीक चलाता है।

(कम से कम, कि मैं इसे कैसे काम करता है लगता है।)

+2

मुझे पूरा यकीन है कि आपको वास्तव में लिंकर त्रुटियों को ठीक करने के बजाय डी रनटाइम को प्रारंभ करने के लिए कॉल करना होगा, लेकिन मैंने वास्तव में पहले कभी ऐसा नहीं किया है, इसलिए मैं ' टी पता नहीं मुझे पता है कि न्यूज ग्रुप में कुछ लोग विंडोज जीयूआई ऐप्स के लिए ऐसा कर रहे हैं, इसलिए _someone_ वहाँ जानता है कि वास्तव में क्या करना है। मैंने अभी डी। लर्न में इसके बारे में एक प्रश्न पोस्ट किया है। उम्मीद है कि, जिसने इसे किया है, वह यहां जवाब देगा। –

+0

हाँ, अगर आप स्मृति आवंटन या यहां तक ​​कि स्थैतिक रचनाकारों की तरह फैंसी सामान चाहते हैं तो आपको स्पष्ट रूप से इसे स्थापित करने की आवश्यकता है :) लेकिन यदि आप डी को बेहतर सी के रूप में उपयोग करना चाहते हैं, तो यह काम कर सकता है। –

+0

यह इस मामले के लिए काम करता प्रतीत होता है, लेकिन मैं इसे एक और अधिक पूरी तरह से शेकडाउन देना चाहता हूं। क्या आप जानते हैं कि यह प्रतीक क्या करना चाहिए? – sholte