非常酷的莴苣 · 中学名师当硕导 ...· 1 月前 · |
酷酷的水煮鱼 · 杨致远和雅虎的故事_企业连线_科技时代_新浪网· 1 月前 · |
坐怀不乱的罐头 · 中华人民共和国民法典(续) - ...· 3 月前 · |
想出国的皮蛋 · 东风风行的微博_微博· 1 年前 · |
悲伤的长颈鹿 · 沃尔沃将为2020年款所有新车型提供SIM卡 ...· 1 年前 · |
我是C++ CLI的新手,来自非托管的C++世界。
我得到了一个错误:
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
发布于 2009-06-03 23:22:28
问题是std::string将作为内部(非公共)类型进行编译。这实际上是VS 2005+中的一个更改:
http://msdn.microsoft.com/en-us/library/ms177253(VS.80).aspx :
默认情况下,本机类型在程序集之外是私有的,默认情况下,本机类型在程序集之外是不可见的。有关程序集外部类型可见性的详细信息,请参阅类型可见性。这一变化主要是由开发人员在引用VisualC++编写的元数据时使用其他不区分大小写的语言的需求驱动的。
您可以使用Ildasm或 反射器 确认这一点,您将看到您的提取方法编译为:
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杂注将本机类型编译为public。
例如,如果您有一个方法Extract2,例如:
void Extract2( std::exception& data_ );
您可以强制将std::exception编译为public,方法是预先包含以下语用语句:
#pragma make_public(std::exception)
此方法现在可跨程序集调用。
不幸的是,make_public不适用于模板化的类型(std::string只是basic_string<>的类型),我不认为您可以做任何事情来使它工作。我建议在所有公共API中使用托管类型System::String^。这还确保您的库可以轻松地从其他CLR语言(如c# )调用。
发布于 2013-08-19 11:29:38
如果您只需访问
internal
方法,那么另一项工作将是将项目作为
朋友大会
进行如下操作:
//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