封装一个包含char *成员的非托管结构
我正在使用从unmanged代码到我托管的C#代码的回调函数。回调有一个参数void* eventData
。 EventData可以是几种不同的结构类型。在我的C#代码中,我将eventData定义为IntPtr
并使用Marshal.PtrToStructure
来获取结构。对于大多数结构我没有问题。但是,我遇到了编组这一个问题:封装一个包含char *成员的非托管结构
//! 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组合,但都没有成功(显然)。我做了一些搜索,没有发现任何与我的情况类似的东西。
由DoseParamters.parameters
成员到IntPtr
和使用JaredPar的答案,这解决了这个问题: https://*.com/questions/188299/marshal-c-struct-array-into-c-sharp
我相信有一个长度属性,你可以把它放在C#中的char *的类型上,使它转换得很好。
实际上有一个转换工具,P/Invoke Interop Assistant,您可能想要查看(在[1]中提到)。它从C代码为interop生成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相似?
'[的MarshalAs(UnmanagedType.ByValArray)]'肯定是不正确的 - 我怀疑它应该是'UnmanagedType.LPArray'代替。 – ildjarn 2012-03-29 20:29:32