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++库问题,如果文章还是没有看懂的,请各位朋友自行下载源代码,调试看看。

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

你可能感兴趣的:(C++)