第三方的SDK是用C# 写的, 我要用VC++ 调用对方的DLL
#using "USIP.Sdk.dll"
using namespace USIP::Sdk
在某个按钮事件中
USIPSdkInstance^pUsipSdkInstance = gcnew USIPSdkInstance; //编译,这里报错C3767
编译报错: error C3767: "USIP::Sdk::USIPSdkInstance::USIPSdkInstance" : 候选函数不可访问,请问什么原因,如何解决?
已经用工具ILDasm 看过,命名空间,类名都是对的。
https://docs.microsoft.com/en-us/cpp/preprocessor/make-public?redirectedfrom=MSDN&view=msvc-160
问题在于std :: string将作为内部(非公共)类型进行编译。这实际上是VS 2005+中的更改:
http://msdn.microsoft.com/zh-cn/library/ms177253(VS.80).aspx:
默认情况下,本机类型在程序集外部是私有的。默认情况下,本机类型现在在程序集外部将不可见。有关部件外部类型可见性的更多信息,请参见类型可见性。此更改主要是由开发人员在引用Visual C ++中编写的元数据时使用其他不区分大小写的语言的需求驱动的。
您可以使用Ildasm或反射器确认这一点,您将看到您的extract方法编译为:
公共不安全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] 内部结构basic_string <char,std :: char_traits <char>,std :: allocator <char>>
注意内部。
不幸的是,您随后将无法从其他程序集中调用此类方法。
在某些情况下,有一种解决方法:您可以使用make_public编译指示强制将本机类型编译为公共类型。
例如,如果您有方法Extract2,例如:
void Extract2(std :: exception&data_);
您可以通过预先包含以下pragma语句来强制将std :: exception编译为公共:
#pragma make_public(std :: exception)
现在可以在程序集之间调用此方法。
不幸的是,make_public不适用于模板类型(std :: string只是basic_string <>的typedef)。我认为您无法做任何事情来使其正常工作。我建议在所有公共API中使用托管类型System :: String ^。这还确保可以轻松地从其他CLR语言(例如c#)调用您的库