.net - 将非空终止字符串传递给非托管代码

标签 .net string interop pinvoke marshalling

考虑将以下结构通过 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/

相关文章:

.net - 10 次连续请求后 HttpWebRequest 超时

c# - 不同的应用程序和线程池线程(或没有)?

java - 使用 SimpleDateFormat 将字符串转换为日期

c - 如何将多个整数组合成一个字符串并在其间添加符号?

.net - 如果可以选择,混合模式程序集与单独的互操作 DLL 的优缺点是什么?

.net - COM/Interop - 支持多个版本

.NET - 是否可以在没有 MVC 的情况下使用 HTML 5 使用 ASP.NET?

c# - 根据语言(当前文化)下载文件

string - 无法将类型 'Int' 的值转换为预期的参数类型 'Index'(又名 'String.CharacterView.Index')

c# - 我们如何将 Word(*.doc/*.docx) 转换为 PDF?