Ответ 1
Проблема заключается в том, что std::string будет компилироваться как внутренний (не публичный) тип. Это фактически изменение VS 2005 +:
http://msdn.microsoft.com/en-us/library/ms177253(VS.80).aspx:
Собственные типы являются закрытыми по умолчанию вне сборки Теперь родные типы не будут отображаться вне сборки по умолчанию. Дополнительную информацию о видимости типа вне сборки см. В разделе Тип видимости. Это изменение в основном было обусловлено потребностями разработчиков, использующих другие, не зависящие от регистра языки языки, при ссылке на метаданные, созданные в Visual С++.
Вы можете подтвердить это с помощью Ildasm или reflector, вы увидите, что ваш метод extract скомпилирован как:
public unsafe void Extract(basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsImplicitlyDereferenced) data_)
с базовым_строком, скомпилированным как:
[StructLayout(LayoutKind.Sequential, Size=0x20), NativeCppClass, MiscellaneousBits(0x40), DebugInfoInPDB, UnsafeValueType]
internal struct basic_string<char,std::char_traits<char>,std::allocator<char> >
Обратите внимание на внутреннее.
К сожалению, вы не можете вызвать такой метод из другой сборки.
В некоторых случаях существует обходное решение: вы можете принудительно скомпилировать родной тип как общедоступный, используя прагму make_public.
например. если у вас есть метод Extract2, например:
void Extract2( std::exception& data_ );
вы можете принудительно скомпилировать std:: exception как общедоступный, предварительно включив этот pragma-оператор:
#pragma make_public(std::exception)
этот метод теперь можно вызывать через сборки.
К сожалению, make_public не работает для шаблонных типов (std::string просто для typedef для basic_string < > ) Я не думаю, что вы можете сделать что-нибудь, чтобы заставить его работать. Я рекомендую использовать управляемый тип System:: String ^ во всех ваших общедоступных API. Это также гарантирует, что ваша библиотека легко может быть вызвана с других языков CLR, таких как С#