本文介绍了传递非空值终止字符串非托管code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的结构要通过TCP发送到一个非托管的DLL

Consider the following struct to be sent over TCP to an unmanaged dll

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct FooMessage
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)]
    public string foo;

    //More fields...
}

使用下面的函数(信贷Cheeso):

Using the following function (credit to 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不 - 和实际使用的最后一个字符(这永远是空的编组)

Problem: The marshaller assumes foo is a null terminated string, whereas the unmanaged dll does not - and actually uses the last char (which always comes out null from the marshaller).

任何想法?

澄清:我不能只是改变SizeConst到43,因为我需要保持消息的总规模,以及下一个字段在结构中的位置(按现有的ICD)

Clarification: I can't just change the SizeConst to 43, because I need to maintain the total size of the message, as well as the position of the next fields in the struct (according to an existing ICD)

推荐答案

由于没有其他的答案已经发布,这里是解决方法我发现

Since no other answer has been posted, here is the workaround I've found

[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...
}

此外href="http://nitoprograms.blogspot.com/2010/02/interop-multidimensional-arrays-of.html" rel="nofollow">通过TCP专家斯蒂芬类似解决方案

这篇关于传递非空值终止字符串非托管code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 11:34