The problem is that std::string will compile as a internal (non public) type. This is actually a change in VS 2005+:
http://msdn.microsoft.com/en-us/library/ms177253(VS.80).aspx:
Native types are private by default outside the assembly
Native types now will not be visible outside the assembly by default. For more information on type visibility outside the assembly, see Type Visibility. This change was primarily driven by the needs of developers using other, case-insensitive languages, when referencing metadata authored in Visual C++.
You can confirm this using Ildasm or reflector, you will see that your extract method is compiled as:
public unsafe void Extract(basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsImplicitlyDereferenced) data_)
with basic_string being compiled as:
[StructLayout(LayoutKind.Sequential, Size=0x20), NativeCppClass, MiscellaneousBits(0x40), DebugInfoInPDB, UnsafeValueType]
internal struct basic_string<char,std::char_traits<char>,std::allocator<char> >
Note the internal.
Unfortunately you are then unable to call a such a method from a different assembly.
There is a workaround available in some cases: You can force the native type to be compiled as public using the make_public pragma.
e.g. if you have a method Extract2 such as:
void Extract2( std::exception& data_ );
you can force std::exception to be compiled as public by including this pragma statement beforehand:
#pragma make_public(std::exception)
this method is now callable across assemblies.
Unfortunately make_public does not work for templated types (std::string just being a typedef for basic_string<>)
I don't think there is anything you can do to make it work. I recommend using the managed type System::String^ instead in all your public API. This also ensures that your library is easily callable from other CLR languages such as c#