对包含char *成员的非托管结构进行编组

时间:2012-03-29 20:25:44

标签: c# c++ marshalling structlayout

我正在使用从无人值守代码到我的托管C#代码的回调函数。回调有一个参数void* eventData。 EventData可以是几种不同的结构类型。在我的C#代码中,我将eventData定义为IntPtr并使用Marshal.PtrToStructure来获取结构。对于大多数结构,我没有问题。但是,我遇到了解决这个问题的问题:

//! Structure for dose parameters

typedef struct
{
    //! the dose in µGrays
    float dose;

    unsigned short nbParameters;
    //! the corresponding parameters specified in the .ini file
    struct Parameters
    {
        //! parameter text
        const char* text;
        //! parameter value
        float value;
    } * parameters;

} DoseParameters;

这是结构的C#定义:

/// <summary>
/// Structure for dose parameters
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct DoseParameters {
    //! the dose in µGrays
    public float dose;

    public ushort nbParameters;
    //! the corresponding parameters specified in the .ini file

    [StructLayout(LayoutKind.Sequential)]
    public struct Parameters{
        //! parameter text        
        public string text;
        //! parameter value        
        public float value;
    }

    [MarshalAs(UnmanagedType.ByValArray)]
    public Parameters[] parameters;
}

正确转换剂量和nbParameters值。这是我正在努力的Parameters数组。长度始终为1,对于那个实例,Parameters.text是无法理解的,并且Parameters.value远大于应有的值。

似乎这与char *是一个不确定的长度有关。虽然,我是StructLayout / MarshalAs的新手,所以不太确定。我玩过各种MarshalAs,LayoutKind.Explicit和FieldOffset组合,但是没有成功(显然)。我做了一些搜索,但没有发现任何与我的情况类似的东西。

2 个答案:

答案 0 :(得分:0)

我相信你可以在C#中设置一个char属性的长度属性,使其转换得很好。

实际上有一个转换工具,P / Invoke Interop助手,您可能想要查看(在[1]中提到)。它从C代码生成C#代码用于互操作。我曾经将它用于一个项目并且运作良好。

[1] http://msdn.microsoft.com/en-us/magazine/cc164193.aspx

编辑:添加工具名称

编辑:http://social.msdn.microsoft.com/Forums/en-us/clr/thread/86412199-da26-4fe4-9450-351f8f3a74b8类似吗?

答案 1 :(得分:0)

通过将DoseParamters.parameters成员更改为IntPtr并使用JaredPar对此的回答来解决此问题: https://stackoverflow.com/questions/188299/marshal-c-struct-array-into-c-sharp