有没有人可以帮我做以下事情?
我有一个用C写的动态链接库,想从C#中调用其中的某个函数。
该函数返回一个指向结构的指针。结构是这样的:
typedef struct
{
char crv_name[40];
char crv_name2[12];
char units[40];
char creator[24];
char index_units[8];
double first_dep_tim;
double last_dep_tim;
double level_spacing;
EmptyValU empty_val;
long num_ele;
}现在,我知道(从C客户端调用此函数)最后一个成员(num_ele)将被设置为1。
现在,倒数第二个成员的类型为EmptyValU,其定义如下:
typedef union
{
double d;
float f;
long l;
ulong ul;
short s;
ushort us;
char c;
}EmptyValU;现在,我可以把它叫做C#,然后在empty_val之前读取所有内容。我对num_ele的值是无稽之谈,因为在empty_val之后,我的内存显然没有对齐。
下面是我的C#代码:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CurveInfo
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string crv_name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string crv_name2;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string units;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string creator;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string index_units;
public double first_dep_tim;
public double last_dep_tim;
public double level_spacing;
[MarshalAs(UnmanagedType.Struct, SizeConst = 8)]
public EmptyValU empty_val;
public long num_ele;
}我将EmptyValU定义为:
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct EmptyValU
{
[FieldOffset(0)]
public double d;
[FieldOffset(0)]
public float f;
[FieldOffset(0)]
long l;
[FieldOffset(0)]
ulong ul;
[FieldOffset(0)]
short s;
[FieldOffset(0)]
ushort us;
[FieldOffset(0)]
char c;
}就像我说的,当我调用返回指向这样一个结构的指针的函数时,所有的值都被正确填充,直到EmptyValU成员,它和num_ele都没有被正确填充。为了保持对齐的正确性,我在C#中定义联合的方式缺少一些东西。
谢谢你的帮助米奇。
发布于 2020-03-25 23:06:01
我已经解决了这个问题。
长整型(和ulong)是4字节宽,但在C#中是8字节宽。
因此,不是:
[FieldOffset(0)]
long l;
[FieldOffset(0)]
ulong ul;我应该有:
[FieldOffset(0)]
int l;
[FieldOffset(0)]
uint ul;因为在C#中,int和uint是4字节宽的。
出于同样的原因,在C#端,而不是:
public long num_ele;我需要:
public int num_ele;现在一切都正常了。
https://stackoverflow.com/questions/60816442
复制相似问题