封送包含 char* 成员的非托管结构

Posted

技术标签:

【中文标题】封送包含 char* 成员的非托管结构【英文标题】:Marshaling an unmanaged struct containing a char* member 【发布时间】:2012-04-13 13:09:25 【问题描述】:

我正在使用从非托管代码到托管 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;

dose 和 nbParameters 值已正确转换。这是我正在努力解决的参数数组。长度始终为 1,对于该实例,Parameters.text 是不可理解的,Parameters.value 远大于应有的值。

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

【问题讨论】:

[MarshalAs(UnmanagedType.ByValArray)] 肯定不正确——我怀疑应该是 UnmanagedType.LPArray 【参考方案1】:

我相信您可以在 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 类似?

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于封送包含 char* 成员的非托管结构的主要内容,如果未能解决你的问题,请参考以下文章

将具有枚举成员的非托管结构编组到 c#

无法封送“返回值”:托管/非托管类型组合无效

从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。”

调用使用 C# 返回结构数组的非托管 dll 函数

将托管类中包含的非托管指针字段传递给非托管代码

如何包含我的非托管 dll 需要的 dll,例如 kernel32.dll