2009-06-03 243 views
13

我是新来的C++ CLI来自非托管C++世界。C++ CLI错误C3767:候选函数不可访问

我得到这个错误:

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(); 
} 

LibTest项目(编译为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; 
} 

编译器错误:

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

的问题是,性病:: string将作为内部(非公共)类型进行编译。这实际上是在VS 2005+的变化:

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

机类型有私人默认大会 原生类型外,现在也不会默认组件之外可见。有关程序集外类型可见性的更多信息,请参阅类型可见性。当引用在Visual C++中编写的元数据时,此更改主要由使用其他不区分大小写的语言的开发人员的需求驱动。

您可以确认这一点使用ILDASM或reflector,您将看到您的提取方法编译:

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

与basic_string的被编译为:

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

注意内部

不幸的是,你不能从另一个程序集调用这样的方法。

在某些情况下可以使用解决方法:您可以使用make_public杂注强制将本机类型编译为公共。

例如如果你有一个方法Extract2如:

void Extract2(std::exception& data_); 

可以强制的std ::例外,由包括这个编译声明事先被编译为市民:

#pragma make_public(std::exception) 

这种方法是目前跨组件调用。

不幸的是,make_public不适用于模板类型(std :: string只是basic_string的typedef> <> 我不认为有任何事情可以使它工作。我建议在所有公共API中使用托管类型System :: String ^。这也保证了你的图书馆从其他CLR语言轻松调用,如C#

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 2014-01-25 08:38:33

1

除了如上所述,解决方案Ò ne可以对模板类型进行子类化以获得非模板类型,并将其定义包含在两个项目中,从而克服上述的一些问题。

+0

此解决方案完美工作 – BlueStrat 2017-07-18 23:04:05

相关问题