Проблема в том, что 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_)
с базовой_строкой, компилируемой как:
[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 как public, предварительно включив этот прагматический оператор:
#pragma make_public(std::exception)
этот метод теперь доступен для всех сборок.
К сожалению, make_public не работает для шаблонных типов (std :: string просто является typedef для basic_string <>)
Я не думаю, что вы можете что-то сделать, чтобы это сработало. Я рекомендую использовать управляемый тип System :: String ^ во всех ваших общедоступных API. Это также гарантирует, что ваша библиотека легко вызывается из других языков CLR, таких как c #