2016-03-07 5 views
8

अगर मैंक्या कोई जानता है कि विज़ुअल सी ++ में मैन्युअल रूप से नामों को कैसे जोड़ना है?

void foo(int c, char v); 

... मेरी .obj में की तरह एक ग में एक समारोह है, यह

_foo 

नाम के एक प्रतीक बन ... प्रति सी नाम नियम mangling के रूप में। यदि मेरे पास .cpp फ़ाइल में एक समान कार्य है, तो यह कंपाइलर-विशिष्ट नाम मैंगलिंग नियमों के अनुसार पूरी तरह से कुछ और बन जाता है। MSVC 12 हमें दे देंगे इस:

[email protected]@[email protected] 

अगर मैं .cpp फ़ाइल में है कि समारोह foo है और मैं यह सी नाम नियम mangling उपयोग करने के लिए (यह मानते हुए मैं अधिक भार के बिना कर सकते हैं) चाहते हैं, हम यह

के रूप में घोषणा कर सकते हैं
extern "C" void foo(int c, char v); 

... जो मामले में, हम अच्छे पुराने

_foo 

को वापस आ गए हैं ... .obj प्रतीक तालिका में।

मेरा सवाल है, क्या यह दूसरी तरफ जाना संभव है? अगर मैं सी ++ नाम को सी फंक्शन के साथ जोड़ना चाहता हूं, तो यह जीसीसी के साथ आसान होगा क्योंकि जीसीसी के नाम मैंगलिंग नियम केवल पहचानकर्ता-अनुकूल पात्रों का उपयोग करते हैं, इस प्रकार foo का उलझन नाम _ZN3fooEic बन जाता है, और हम आसानी से

लिख सकते हैं
void ZN3fooEic(int c, char v); 

माइक्रोसॉफ्ट संकलक-भूमि में वापस, मैं स्पष्ट रूप से एक समारोह जिसका नाम एक पूरी तरह से अमान्य पहचानकर्ता

void [email protected]@[email protected](int c, char v); 

कहा जाता है नहीं बना सकते ... लेकिन मैं अभी भी उस समारोह की तरह साथ दिखाने के लिए चाहते हैं .obj प्रतीक तालिका में उस प्रतीक का नाम।

कोई विचार? मैंने विजुअल सी ++ के समर्थित प्रागम्स को देखा है, और मुझे कुछ भी उपयोगी नहीं दिख रहा है।

+3

@mustafagonul मैं demangle की कोशिश नहीं कर रहा हूँ - मैं वध करने के लिए कोशिश कर रहा हूँ। –

+2

भले ही आप ऐसा कर सकें, आपको किसी भी तरह से एबीआई से मेल खाना पड़ेगा। आप इस पर गलत पेड़ भड़क रहे हैं। इसके लिए बाहरी "सी" का प्रयोग करें और सीमाएं स्वीकार करें। – xaxxon

+2

@ mustafagonul आप इसे काफी समझ नहीं रहे हैं। मुझे पता है कि उलझन और उलझन वाला नाम क्या है। मैं एक सी फाइल में नकली सी ++ नाम मैंगलिंग करना चाहता हूँ। –

उत्तर

5

आप __identifier का उपयोग कर ऐसा कर सकते हैं:

#include <stdio.h> 

#pragma warning(suppress: 4483) 
extern "C" void __cdecl __identifier("[email protected]@[email protected]")(int c, char v) 
{ 
    printf("%d %c\n", c, v); 
} 

void __cdecl foo(int, char); 

int main() 
{ 
    foo(10, 'x'); 
} 
+0

क्या आपको विश्वास करने का कोई कारण है कि यह वास्तव में काम करता है? मैंने अभी कोशिश की है, यह केवल सी ++ कीवर्ड स्वीकार करता है, मनमानी तार नहीं। –

+1

@TurkeyMan यह काम करता है। '# प्रज्ञा चेतावनी (दबाने: 4483) 'आवश्यक है। यदि आप इसे छोड़ देते हैं, तो आपको 'चेतावनी C4483: वाक्यविन्यास त्रुटि: अपेक्षित सी ++ कीवर्ड' मिलेगा, जो डिफ़ॉल्ट रूप से एक त्रुटि है। –

+0

@JamesMcNellis यह वही है जो मैं ढूंढ रहा था।केमिलांड के दृष्टिकोण के रूप में आविष्कारशील होने के नाते, मुझे लगता है कि मैं इस पर स्वीकार्य उत्तर स्विच करने जा रहा हूं (बेशक इन दोनों उत्कृष्ट उत्तरों को अप-वोटिंग)। –

7

आप सही हैं। यह (सीधे) संभव नहीं है (नोट: वीएससी ++ पर भरोसा न करें)। हालांकि, अगर आपको वास्तव में इसकी आवश्यकता है तो निफ्टी वर्कअराउंड मौजूद है। सबसे पहले, C++ फ़ाइल ...

extern "C" int proxy(int i, char c); 

int foo(int i, char c) 
{ 
    return proxy(i, c); 
} 

फिर, सी फाइल में ...

int proxy(int i, char c) 
{ 
    // Do whatever you wanna do here 
} 

किसी भी घायल नाम टाइप करने के बिना, आप अब कॉल करने में सक्षम हैं foo फ़ंक्शन, जो वास्तव में सी फ़ंक्शन proxy के आस-पास एक रैपर है। यह आपको वही प्रभाव देता है जैसे proxy वास्तव में foo था, सी ++ के दृष्टिकोण से। यहां एक दंड निश्चित रूप से एक त्वरित 'एन' गंदे समारोह कॉल है। यदि एबीआई इसे अनुमति देता है, और संकलक पर्याप्त स्मार्ट है, तो इसे एक JMP x86 निर्देश के साथ प्रतिस्थापित किया जा सकता है।

एक और तरीका है सी में एक समारोह foo लिखने के लिए हो सकता है, और उसके बाद का उपयोग MinGW के objcopy आदेश प्रतीक नाम बदलने के लिए में ...

$ objcopy --redefine-sym "[email protected]@[email protected]" foobar.obj 

मैं सुनिश्चित नहीं हूं कि अगर सिर्फ VSC++ उपकरणों के साथ संभव है। यह बहुत अस्थिर, अयोग्य, और हैकी वैसे भी होगा।

+1

फ़ंक्शन प्रस्तावों के साथ होने वाले कई कारणों से मैं काफी कुछ नहीं चाहता था, लेकिन यह एकमात्र समाधान हो सकता है। –

+1

@ टेडमिडलटन: संपादन देखें। वास्तव में एक और समाधान है। – 3442

+1

mingw में objcopy का उपयोग वास्तव में एक बहुत अच्छा समाधान की तरह लगता है। धन्यवाद! –

6

आप इसे .DEF फ़ाइल का उपयोग करके काम करने के लिए प्राप्त कर सकते हैं। अपने foo.cpp में अपने कार्य को परिभाषित करें:

void foo(int c, char v) { ... } 

फिर लिंकर करने के लिए एक def file गुजरते हैं जो इस तरह दिखता है:

LIBRARY mylib 
EXPORTS 
    [email protected]@[email protected]=_foo 

अस्वीकरण: अपरीक्षित, मैं कुछ विवरण छूटे हुए हों।

+0

इस समय मेरे पास केवल MSVC2008 तक पहुंच है, और यह समाधान * काम नहीं करता *। असल में लिंकर एक विशेष चरित्र के रूप में डीफ़ फाइल में "@" को व्याख्या करता है, इस प्रकार परिणामी निर्यातित प्रतीक केवल "? Foo" होता है। शायद यह संकलक के एक नवीनतम संस्करण में बदल गया है। – sbabbi

+0

मैंने वास्तव में MSVC2013 पर भी यह कोशिश की, और यह काम नहीं करता - जैसा कि आपने कहा था, यह पहले '@' चरित्र पर छंटनी करता है। आपको लगता है कि ऐसा इसलिए था क्योंकि लिंकर सामान्य चरित्र के साथ @ चरित्र को भ्रमित कर रहा था, लेकिन ऐसा नहीं है - जब मेरे पास "? Foo @@ YAXHD @ Z = _foo @ 24" जैसा प्रतीक है, जैसा कि आपको मिलता है ? foo लेकिन यह अभी भी सही ordinal मिलता है, 24. –

संबंधित मुद्दे