C ++ CLI错误C3767:候选函数不可访问 [英] C++ CLI error C3767: candidate function(s) not accessible

查看:3527
本文介绍了C ++ CLI错误C3767:候选函数不可访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是来自非托管C ++世界的C ++ CLI。

I'm new to C++ CLI coming from unmanaged C++ world.

我收到此错误:

candidate function(s) not accessible

这里是确切的代码:

Lib Project(编译为.dll项目)

// Lib.h

#pragma once

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

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

// Lib.cpp

//Lib.cpp

#include "Lib.h"

Lib::Lib(void)
{
}

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

LibTest项目(编译为application.exe)

// LibTest.h

// LibTest.h

#pragma once

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

// LibTest.cpp

// 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 +的一个变化:

The problem is that std::string will compile as a internal (non public) type. This is actually a change in VS 2005+:

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

默认情况下,本地类型在程序集之外是私有的
默认情况下,本地类型在组件外部不可见。有关装配体外部类型可见性的详细信息,请参阅类型可见性。此更改主要是由于在引用使用Visual C ++创作的元数据时,使用其他不区分大小写的语言的开发人员的需求。

Native types are private by default outside the assembly Native types now will not be visible outside the assembly by default. For more information on type visibility outside the assembly, see Type Visibility. This change was primarily driven by the needs of developers using other, case-insensitive languages, when referencing metadata authored in Visual C++.

Ildasm或反射器,您将看到您的提取方法编译为:

You can confirm this using Ildasm or reflector, you will see that your extract method is compiled as:

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

将basic_string编译为:

with basic_string being compiled as:

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

请注意内部

不幸的是,您无法从不同的程序集中调用这样的方法。

Unfortunately you are then unable to call a such a method from a different assembly.

在某些情况下有一个解决方法:您可以使用make_public pragma强制将本机类型编译为public。

There is a workaround available in some cases: You can force the native type to be compiled as public using the make_public pragma.

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

e.g. if you have a method Extract2 such as:

void Extract2( std::exception& data_ );

您可以强制std :: exception通过预先包含此pragma语句被编译为public: p>

you can force std::exception to be compiled as public by including this pragma statement beforehand:

#pragma make_public(std::exception)

此方法现在可在程序集中调用。

this method is now callable across assemblies.

不幸的是,make_public不适用于模板类型(std :: string只是一个typedef的basic_string<>)
我不认为有什么可以做到使它工作。我建议使用托管类型System :: String ^而不是所有的公共API。这也确保您的库可以从其他CLR语言(如c#

Unfortunately make_public does not work for templated types (std::string just being a typedef for basic_string<>) I don't think there is anything you can do to make it work. I recommend using the managed type System::String^ instead in all your public API. This also ensures that your library is easily callable from other CLR languages such as c#

这篇关于C ++ CLI错误C3767:候选函数不可访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆