C++ cli C++;CLI错误C3767:候选函数不可访问 我是来自非托管C++世界的C++ CLI新手。
我得到了这个错误:C++ cli C++;CLI错误C3767:候选函数不可访问 我是来自非托管C++世界的C++ CLI新手。,c++-cli,C++ Cli,我得到了这个错误: candidate function(s) not accessible 当我将std::string作为方法参数的一部分传递时 下面是确切的代码: Lib项目(编译为.dll项目) //Lib.h #pragma once public ref class Lib { public: Lib(void); public: void Extract( std::string& data_ ); }; //Lib.cpp #include "Lib.h
candidate function(s) not accessible
当我将std::string作为方法参数的一部分传递时
下面是确切的代码:
Lib项目(编译为.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项目(编译为application.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
问题是std::string将编译为内部(非公共)类型。这实际上是VS 2005+的一个变化: : 默认情况下,本机类型在程序集外部是私有的 默认情况下,本机类型现在在程序集外部不可见。有关部件外部类型可见性的详细信息,请参见类型可见性。这种变化主要是由开发人员使用其他不区分大小写的语言驱动的,当引用VisualC++中的元数据。 您可以使用Ildasm确认这一点,或者,您将看到您的提取方法编译为:
public unsafe void Extract(basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsImplicitlyDereferenced) data_)
[StructLayout(LayoutKind.Sequential, Size=0x20), NativeCppClass, MiscellaneousBits(0x40), DebugInfoInPDB, UnsafeValueType]
internal struct basic_string<char,std::char_traits<char>,std::allocator<char> >
您可以通过事先包含以下pragma语句,强制将std::exception编译为public:
#pragma make_public(std::exception)
此方法现在可以跨程序集调用
不幸的是,make_public不适用于模板类型(std::string只是基本_字符串的typedef)
我不认为你能做什么来让它工作。我建议在所有公共API中改用托管类型System::String^。这还可以确保您的库可以轻松地从其他CLR语言(如c#调用,如果您只需访问
内部
方法,另一种解决方法是使项目如下所示:
//Lib项目
#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);
};
#pragma一次
#用作朋友
参考类LibTest
{
公众:
LibTest(无效);
};
除了上述解决方案外,还可以对模板类型进行子类化,以获得非模板类型,并在两个项目中包含其定义,从而克服上述一些问题。#pragma make_public仅从声明到源代码文件末尾有效。因此,在使用#pragma make_public指令时,有必要确保在其他文件中未使用相同的本机类型。在这种情况下,有必要在使用本机类型的所有文件中应用#pragma make_public。否则,链接器可能会报告错误LNK2022元数据操作失败(80131195):自定义属性不一致。如果要将“字符串”传递给函数@benschwehn而不是使用string
,则可以使用char*
,而不是sivabudh@BenSchwen
#pragma once
#using <Lib.dll> as_friend
ref class LibTest
{
public:
LibTest(void);
};