我是来自非托管C++世界的C++ CLI的新手.
我收到这个错误:
candidate function(s) not accessible
Run Code Online (Sandbox Code Playgroud)
当我传递一个std :: string作为方法参数的一部分.
这是确切的代码:
Lib Project(编译为.dll项目)
//Lib.h
#pragma once
public ref class Lib
{
public:
Lib(void);
public:
void Extract( std::string& data_ );
};
Run Code Online (Sandbox Code Playgroud)
//Lib.cpp
#include "Lib.h"
Lib::Lib(void)
{
}
void Lib::Extract( std::string& data_ )
{
data_.empty();
}
Run Code Online (Sandbox Code Playgroud)
LibTest项目(编译为application.exe)
// LibTest.h
#pragma once
ref class LibTest
{
public:
LibTest(void);
};
Run Code Online (Sandbox Code Playgroud)
// LibTest.cpp
#include "LibTest.h"
LibTest::LibTest(void)
{
Lib^ lib = gcnew Lib;
lib->Extract( std::string("test") );
}
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器错误:
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
Run Code Online (Sandbox Code Playgroud)
Ben*_*ehn 25
问题是std :: string将编译为内部(非公共)类型.这实际上是VS 2005+的变化:
http://msdn.microsoft.com/en-us/library/ms177253(VS.80).aspx:
默认情况下,默认情况下,本机类型在程序集外部默认为私有类型.有关程序集外部类型可见性的更多信息,请参阅类型可见性.在引用Visual C++中创建的元数据时,此更改主要由使用其他不区分大小写的语言的开发人员的需求驱动.
您可以使用Ildasm或反射器确认这一点,您将看到您的提取方法编译为:
public unsafe void Extract(basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsImplicitlyDereferenced) data_)
Run Code Online (Sandbox Code Playgroud)
将basic_string编译为:
[StructLayout(LayoutKind.Sequential, Size=0x20), NativeCppClass, MiscellaneousBits(0x40), DebugInfoInPDB, UnsafeValueType]
internal struct basic_string<char,std::char_traits<char>,std::allocator<char> >
Run Code Online (Sandbox Code Playgroud)
注意内部.
不幸的是,你无法从不同的程序集调用这样的方法.
在某些情况下有一种解决方法:您可以使用make_public pragma强制将本机类型编译为公共类型.
例如,如果您有方法Extract2,例如:
void Extract2( std::exception& data_ );
Run Code Online (Sandbox Code Playgroud)
您可以通过事先包含此pragma语句来强制将std :: exception编译为public:
#pragma make_public(std::exception)
Run Code Online (Sandbox Code Playgroud)
此方法现在可以跨程序集调用.
不幸的是,make_public对于模板化类型不起作用(std :: string只是basic_string <>的typedef)我不认为你可以做任何事情来使它工作.我建议在所有公共API中使用托管类型System :: String ^.这也确保您的库可以从其他CLR语言轻松调用,例如c#
| 归档时间: |
|
| 查看次数: |
15985 次 |
| 最近记录: |