• 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

  • 相关阅读:
    C#捕获摄像头进行拍照和录像资料总结
    MySQL:日期函数、时间函数总结(MySQL 5.X)
    apache 虚拟主机详细配置:http.conf配置详解
    [转载文章]6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
    GetType和typeof的区别
    [转]C#读写xml文件
    DateTime 格式化
    jquery sortable 插件参数详解
    [转]一个人脸检测器
    why SOA
  • 原文地址:https://www.cnblogs.com/ltlly/p/4120362.html
Copyright © 2020-2023  润新知