C# 调用c++报错可能性分析

1.在调用之前,可以用工具(Dependency)检测下c++库所依赖的文件,看是否有错误。如果有错误,请先下补充所需运行环境。

2.如果c++ 函数 形参需要C#传入结构体,可如下:

1 [StructLayout(LayoutKind.Sequential)]//作用:按顺序排列,防止C#编译器打乱,起到与C++那边保持一致。
2 public struct mwEdgeFileHeader 
3 {
4 uint type;    //切面数据文件头类型固定为0xFF0000F1
5 uint version;    //初始版本为1,更改后依次提升
6 uint length;    //头信息的长度,字节为单位,此为20
7 uint content_offset;    //存储的数据起始在文件中的偏移量,此为20+1
8 uint content_length;    //存储的数据长度
9 };
View Code

如果 上面结构体中有数组,C#定义结构体,必须指明结构体的长度。注意:c++端必须指明数组长度,不可使用动态长度(目前我测试的时候是这样子,可能不全,希望有遇到能动态的朋友,私信我,大家一起探讨下,谢谢!)

c++代码:

 1 typedef struct _edgefile{
 2     char name[512];                //此数据对应图像文件的名字
 3     uint32_t width;                //图像的宽度
 4     uint32_t height;            //图像的高度
 5     double center_x;            //瞳孔X轴方向位置
 6     double center_y;            //瞳孔Y轴方向位置
 7     double pupils_dia;            //瞳孔的直径
 8     double coef[9];                //侧面图像校正矩阵
 9     double ratio[2];            //侧面图像和正面图像的像素长
10     uint32_t info_count;        //所包含的边缘信息的数量
11 }mwEdgeContents;
View Code

C#转换代码:

 1     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
 2     public struct mwEdgeContents 
 3     {
 4         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
 5         public char[] name;                //此数据对应图像文件的名字
 6         public UInt32 width;                //图像的宽度
 7         public UInt32 height;            //图像的高度
 8         public double center_x;            //瞳孔X轴方向位置
 9         public double center_y;            //瞳孔Y轴方向位置
10         public double pupils_dia;            //瞳孔的直径
11         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
12         public double[] coef;                //侧面图像校正矩阵
13         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
14         public double[] ratio;            //侧面图像和正面图像的像素长
15         public UInt32 info_count;        //所包含的边缘信息的数量
16     };
View Code

3.如果c++ 函数 返回值是结构体指针,C# 请用intptr接收,然后C#再把intptr转结构体,如下:

C#翻译的结构体: 

 1  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
 2     public struct MwEdges
 3     {
 4         UInt32 count;
 5         UInt32 lenght;
 6         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
 7         double[] p11;
 8         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
 9         double[] p12;
10         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
11         double[] p21;
12         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
13         double[] p22;
14         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
15         double[] p31;
16         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
17         double[] p32;
18         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
19         double[] p41;
20         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
21         double[] p42;
22         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
23         double[] p51;
24         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1280)]
25         double[] p52;
26         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
27         Point[]    poiAngle;
28         double dAngle;
29     };
View Code

C#调用该结构体:

 1   string filename = (Directory.GetCurrentDirectory() + "\\20140707143436\\result\\" + "flank01L.edg");
 2             MwEdges picCfg = new MwEdges();
 3             int size = Marshal.SizeOf(picCfg);
 4             byte[] bPicCfg = new byte[size];
 5 
 6             //即调用某个函数从C++的Dll获取到结构体的bPicCfg,如果这个函数调用失败或者不调用,则不会出现问题。
 7             IntPtr ipPicCfg = Marshal.AllocHGlobal(size);
 8             Marshal.Copy(bPicCfg, 0, ipPicCfg, bPicCfg.Length);
 9 
10             //问题出现在这里。运行时报 引发类型为“System.ExecutionEngineException”的异常。 这个错误。
11             IntPtr data = ReadEdgeDatas(filename);
12             picCfg = (MwEdges)Marshal.PtrToStructure(data, picCfg.GetType());
View Code

 文章写的有点乱,但主要目的还是为了解决C#调用c++库问题,如果文章还是没有看懂的,请各位朋友自行下载源代码,调试看看。

https://files.cnblogs.com/ltlly/testCSharpUseC.rar

posted @ 2014-11-25 10:30  ltlly  阅读(304)  评论(0编辑  收藏  举报