VC++ /clr 调用第三方.Net 的dll,报错C3767:候选函数不可访问

第三方的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#)调用您的库