求助C#大牛!调用C++编译的dll数据类型转换的问题。
我将下面一段C++编译成dll,其中函数的参数是一个结构体数组,但是在C#中调用这个函数就出现了问题:
#include "stdafx.h"
typedef struct tagFIELD_st{
char name[64];
unsigned short type;
unsigned int len;
double simdis;
char tblname[64];
}FIELD_st;
extern "C" __declspec(dllexport) int TestStruct(int field_count,FIELD_st fields[])
{
for (int i=0; i<field_count; i++)
{
switch (fields[i].type) {
case 0x0002:
break;
case 0x0008:
break;
case 0x0010:
break;
case 0x0028:
break;
case 0x0012:
break;
case 0x0014:
break;
case 0x0022:
break;
case 0x0030:
if (fields[i].simdis<0) return -1;
break;
case 0x0004:
if (fields[i].len<=1) return -2;
break;
default:
return -3;
break;
};
if (strlen(fields[i].name)==0) return -4;
return 0;
}
}
然后用下面的一段C#代码调用这个dll中的函数TestStruct,结果总是在switch中进入default,返回-3,以下是C#的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct FIELD_st
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string name;
public UInt16 type;
public UInt32 len;
public Double simdis;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string tblname;
}
[DllImport("D:\\mongoebase\\StructDll\\Debug\\StructDll.dll")]
public static extern int TestStruct(int field_count, [Out] FIELD_st[] fields);
static void Main(string[] args)
{
FIELD_st[] fb = new FIELD_st[4];
fb[0].name = "BNO";
fb[0].type =0x0008;
fb[1].name = "BNAME";
fb[1].type = 0x0004;
fb[1].len = 40;
fb[2].name = "ANO";
fb[2].type = 0x0008;
fb[3].name = "COVER";
fb[3].type = 0x0008;
fb[3].len = 0;
fb[3].simdis = 0.172;
int result = TestStruct(4, fb);
Console.WriteLine(result);
Console.Read();
}
}
}
在C#中调用TestStruct函数,传递的结构体数组参数fb的每个元素的type会在TestStruct中的switch语句中进行比较,我给这个数组的type赋值都是0x0004或者0x0008,但是执行在switch语句中却没有进入case 0x0004和case 0x0008,而是全部都进入了default,请问这是为什么?是我将C中的struct结构转换到C#中有问题吗?但是我查找过很多资料说C中的struct结构转换到C#中就是这样写的啊。求助各位大神!
------解决方案--------------------
C# code
//Pack 控制类或结构的数据字段在内存中的对齐方式。
[StructLayout(LayoutKind.Sequential,Pack=1)]
public struct FIELD_st
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string name;
public UInt16 type;
public UInt32 len;
public Double simdis;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string tblname;
}