2009-06-03 12 views
13

मैं अप्रबंधित सी ++ दुनिया से आने वाले सी ++ सीएलआई के लिए नया हूं।सी ++ सीएलआई त्रुटि सी 3767: उम्मीदवार फ़ंक्शन उपलब्ध नहीं हैं

मैं इस त्रुटि हो रही है:

candidate function(s) not accessible 

जब मैं विधि तर्क के हिस्से के रूप में एक std :: स्ट्रिंग गुजरती हैं।

लिब परियोजना (.dll परियोजना के रूप में संकलित)

//Lib.h

#pragma once 

public ref class Lib 
{ 
public: 
    Lib(void); 

public: 
    void Extract(std::string& data_); 
}; 

//Lib.cpp

#include "Lib.h" 

Lib::Lib(void) 
{ 
} 

void Lib::Extract(std::string& data_) 
{ 
    data_.empty(); 
} 
:

यहाँ सटीक कोड है

लिबटेस्ट प्रोजेक्ट (एप्पल के रूप में संकलित ication.exe)

// LibTest.h

#pragma once 

ref class LibTest 
{ 
public: 
    LibTest(void); 
}; 

// LibTest.cpp

#include "LibTest.h" 

LibTest::LibTest(void) 
{ 
    Lib^ lib = gcnew Lib; 
    lib->Extract(std::string("test")); 
} 

int main() 
{ 
    return 0; 
} 

कंपाइलर त्रुटि:

1>------ Build started: Project: LibTest, Configuration: Debug Win32 ------ 
1>Compiling... 
1>LibTest.cpp 
1>.\LibTest.cpp(7) : error C3767: 'Lib::Extract': candidate function(s) not accessible 

उत्तर

23

समस्या यह है कि एसटीडी है :: स्ट्रिंग एक आंतरिक (गैर सार्वजनिक) प्रकार के रूप में संकलित होगा।

http://msdn.microsoft.com/en-us/library/ms177253(VS.80).aspx:

मूल निवासी प्रकार अब विधानसभा मूल निवासी प्रकार के बाहर डिफ़ॉल्ट से निजी हैं डिफ़ॉल्ट रूप से विधानसभा के बाहर नहीं दिखाई देंगे यह वास्तव में वी.एस. 2005+ में एक परिवर्तन है। असेंबली के बाहर प्रकार दृश्यता के बारे में अधिक जानकारी के लिए, दृश्य दृश्यता देखें। विज़ुअल सी ++ में मेटाडेटा को संदर्भित करते समय यह परिवर्तन प्राथमिक रूप से अन्य, केस-असंवेदनशील भाषाओं का उपयोग करके डेवलपर्स की ज़रूरतों से प्रेरित था।

आप इस ILDASM या reflector का उपयोग कर पुष्टि कर सकते हैं, आप अपने निकालने विधि संकलित किया गया है देखेंगे के रूप में:

[StructLayout(LayoutKind.Sequential, Size=0x20), NativeCppClass, MiscellaneousBits(0x40), DebugInfoInPDB, UnsafeValueType] 
internal struct basic_string<char,std::char_traits<char>,std::allocator<char> > 

नोट आंतरिक:

public unsafe void Extract(basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsImplicitlyDereferenced) data_) 

basic_string साथ के रूप में संकलित किया जा रहा ।

दुर्भाग्य से आप एक अलग असेंबली से ऐसी विधि को कॉल करने में असमर्थ हैं।

कुछ मामलों में एक कामकाज उपलब्ध है: आप मूल प्रकार को मेक_पब्लिक प्रागमा का उपयोग करके जनता के रूप में संकलित करने के लिए मजबूर कर सकते हैं।

उदा

void Extract2(std::exception& data_); 

आप std :: अपवाद मजबूर कर सकते हैं इस pragma बयान पहले से शामिल करके सार्वजनिक रूप संकलित की: यदि आप एक विधि Extract2 जैसे है

#pragma make_public(std::exception) 

इस विधि अब विधानसभाओं भर में प्रतिदेय है।

दुर्भाग्य make_public टेम्प्लेट प्रकार मुझे नहीं लगता कि कुछ भी आप इसे काम करने के लिए कुछ नहीं कर सकता है (std :: स्ट्रिंग सिर्फ basic_string <> के लिए एक typedef जा रहा है) के लिए काम नहीं करता। मैं आपके सभी सार्वजनिक एपीआई में प्रबंधित प्रकार सिस्टम :: स्ट्रिंग^का उपयोग करने की सलाह देता हूं। यह भी सुनिश्चित करता है कि अपने पुस्तकालय में इस तरह के सी # के रूप में अन्य CLR भाषाओं से आसानी से प्रतिदेय है

4

आप बस internal तरीकों का उपयोग करना चाहिए कि क्या किसी अन्य काम के आसपास इस तरह Friend Assemblies के रूप में परियोजनाओं को बनाने की जाएगी:

// लिब परियोजना

#pragma once 

//define LibTest as friend assembly which will allow access to internal members 
using namespace System; 
using namespace System::Runtime::CompilerServices; 
[assembly:InternalsVisibleTo("LibTest")]; 

public ref class Lib 
{ 
public: 
    Lib(void); 

public: 
    void Extract(std::string& data_); 
}; 

// LibTest परियोजना

#pragma once 

#using <Lib.dll> as_friend 

ref class LibTest 
{ 
    public: 
    LibTest(void); 
}; 
+1

धन्यवाद, इसने मेरी समस्या हल की – weidi

1

, ऊपर वर्णित समाधान के अलावा ओ ne एक गैर-टेम्पलेट प्रकार प्राप्त करने के लिए टेम्पलेट प्रकार को उपclass कर सकते हैं, और दोनों परियोजनाओं में इसकी परिभाषा शामिल कर सकते हैं, इस प्रकार ऊपर वर्णित कुछ समस्याओं पर काबू पाने।

+0

यह समाधान पूरी तरह से काम किया – BlueStrat

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