0

我正在使用从非托管代码到托管 C# 代码的回调函数。回调有一个参数void* eventData。EventData 可以是几种不同的结构类型。在我的 C# 代码中,我将 eventData 定义为 anIntPtr并用于 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 值已正确转换。这是我正在努力解决的参数数组。长度始终为 1,对于该实例,Parameters.text 没有什么可理解的,Parameters.value 远大于应有的值。

似乎这与 char * 是不确定的长度有关。虽然,我是新来的 StructLayout/MarshalAs 的东西所以不太确定这一切。我玩过各种 MarshalAs、LayoutKind.Explicit 和 FieldOffset 组合,但没有成功(显然)。我已经进行了一些搜索,但没有找到与我的情况相似的任何东西。

4

2 回答 2

0

我相信您可以在 C# 中的 char* 类型上添加一个长度属性,以使其转换得很好。

实际上有一个转换工具,P/Invoke Interop Assistant,您可能想要查看(在 [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类似?

于 2012-03-29T20:36:34.097 回答
0

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

于 2012-03-30T21:01:17.220 回答