2009-06-03 12 views
13

Je suis novice en matière de CLI C++ provenant du monde C++ non géré.Erreur CLI C++ C3767: fonction (s) candidate (s) non accessible (s)

Je reçois cette erreur:

candidate function(s) not accessible 

quand je passe un std :: string dans le cadre de l'argument de la méthode.

Voici le code exact:

Projet Lib (compilé en tant que projet .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(); 
} 

Projet LibTest (compilé en tant que appl 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; 
} 

compilateur Erreur:

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 

Répondre

23

Le problème est que std :: string sera compilé en tant que type interne (non public). Ceci est en fait un changement de VS 2005+:

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

types autochtones sont privés par défaut extérieur de l'ensemble types autochtones maintenant ne seront pas visibles en dehors de l'assemblée par défaut. Pour plus d'informations sur la visibilité de type en dehors de l'assemblage, voir Type de visibilité. Cette modification a été principalement motivée par les besoins des développeurs utilisant d'autres langages insensibles à la casse, lors du référencement des métadonnées créées dans Visual C++.

Vous pouvez confirmer en utilisant Ildasm ou reflector, vous verrez que votre méthode d'extraction est compilé sous la forme:

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

avec basic_string être compilé comme:

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

Notez le interne .

Malheureusement, vous ne pouvez pas appeler une telle méthode à partir d'un assemblage différent.

Il existe une solution de contournement disponible dans certains cas: Vous pouvez forcer la compilation du type natif en tant que public à l'aide du pragma make_public.

par exemple.si vous avez une méthode Extract2 tels que:

void Extract2(std::exception& data_); 

vous pouvez forcer std :: exception à être compilé en public en incluant cette déclaration pragma préalable:

#pragma make_public(std::exception) 

cette méthode est maintenant appelable dans les assemblées.

Malheureusement, make_public ne fonctionne pas pour les types de templates (std :: string étant juste un typedef pour basic_string <>) Je ne pense pas que vous puissiez faire quelque chose pour le faire fonctionner. Je recommande d'utiliser le type géré System :: String^dans toutes les API publiques. Cela garantit également que votre bibliothèque est facilement appelable d'autres langues CLR, comme C#

4

si vous devez simplement accéder aux internal méthodes un autre travail autour serait faire les projets Friend Assemblies comme ça:

// Lib projet

#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 projet

#pragma once 

#using <Lib.dll> as_friend 

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

merci, cela a résolu mon problème – weidi

1

En plus des solutions décrites ci-dessus, o ne peut sous-classer le type de modèle pour obtenir un type sans modèle, et inclure sa définition dans les deux projets, surmontant ainsi certains des problèmes mentionnés ci-dessus.

+0

Cette solution a parfaitement fonctionné – BlueStrat

Questions connexes