考虑将以下结构通过 TCP 发送到非托管 dll
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct FooMessage
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)]
public string foo;
//More fields...
}
使用以下函数(归功于 Cheeso ):
public byte[] RawSerialize( T item )
{
int rawSize = Marshal.SizeOf( typeof(T) );
IntPtr buffer = Marshal.AllocHGlobal( rawSize );
Marshal.StructureToPtr( item, buffer, false );
byte[] rawData = new byte[ rawSize ];
Marshal.Copy( buffer, rawData, 0, rawSize );
Marshal.FreeHGlobal( buffer );
return rawData;
}
问题:编码器假定 foo 是一个空终止的字符串,而非托管 dll 没有 - 实际上使用最后一个字符(它总是从编码器中输出为空)。
有任何想法吗 ?
澄清 : 我不能只把SizeConst改成43,因为我需要维护消息的总大小,以及结构体中下一个字段的位置(根据现有的ICD)
最佳答案
由于没有发布其他答案,这里是 workaround我找到了
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct FooMessage
{
// use this for non-null-terminated strings
// use default encoder to convert to and from string
[MarshalAs(UnmanagedType.ByValArray, SizeConst=42)]
public char[] foo;
//More fields...
}
还有一个 similar TCP 专家 Stephen Cleary 的解决方案
关于.net - 将非空终止字符串传递给非托管代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3435163/