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