首页 新闻 会员 周边 捐助

C#调用C++的dll问题

0
悬赏园豆:20 [已解决问题] 解决于 2013-05-04 08:31

C++中的方法为api_ihuReadCurrentValue1,方法的各项参数说明如下:

 //api_ihuReadCurrentValue1
        //功能:查询多个标签点的实时值
        //参数说明:
        //long serverhandle                 in连接句柄
        //int number_of_tags                 in查询点数
        //char *tagnames                         in      点名字符串,以逗号拼接,如:"a,b"
        //float *tagvalues                         out 数组,查询返回的值,与tagnames数组对应
        //IHU_TIMESTAMP *timestampsout结构体数组,返回的时间戳
        //int *tagerrs                                out数组,1-查询成功,0-查询失败
        //char *retmessage                         out错误信息描述
        //返回值:
        //>0--IH函数返回错误
        //0--成功
        //<0-失败,其中-50:异常,-100:加载错误,错误信息参考retmessage

我在C#中声明该方法如下:

定义C++中的结构体:

[StructLayout(LayoutKind.Sequential)]
    public struct IHU_TIMESTAMP
    {
        public int Seconds;
        public int Subseconds;
    }

声明C++中的方法

[DllImport("IHAPIDLLS.dll", EntryPoint = "api_ihuReadCurrentValue1", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
 public static extern int Api_ihuReadCurrentValue1(int serverhandle, int number_of_tags, string tagnames, float[] tagvalues,IntPtr timestamps, ref int tagerrs, StringBuilder retmessage);

输出的结构体数组我用IntPtr类型,请问,C#中对应C++的类型是否正确?另外,我传入结构体数组调用该方法是这样做的:

                    string[] strarr = pointStr.Split(',');
                    if (strarr == null || strarr.Length <= 0)
                        return "";
                    int count = strarr.Length;
                    //记录温度点数据的数组
                    float[] floatA = new float[count];

                    int size = Marshal.SizeOf(typeof(IHU_TIMESTAMP));
                    IHU_TIMESTAMP[] IHU_TIMESPAN = new IHU_TIMESTAMP[count];

                    //查询点数据成功与否的标志变量,1表示查询成功;0表示查询失败
                    int tagerrs = 0;
                    //接收查询记录的相关信息(比如查询成功、查询失败等)
                    StringBuilder queryLog = new StringBuilder(15);

                    IntPtr parrStudyRec = Marshal.AllocHGlobal(Marshal.SizeOf(size * count));
                    int run = (int)parrStudyRec;
                    for (int i = 0; i < count; i++)
                    {
                        //IHU_TIMESPAN[i] = new IHU_TIMESTAMP();
                        Marshal.StructureToPtr(IHU_TIMESPAN[i], (IntPtr)run, true);
                        run += size;
                    } 

                    //读取输出的点数值
                    int result1 = IHUOperatorClass.Api_ihuReadCurrentValue1(connectHandler, count, pointStr, floatA, parrStudyRec, ref tagerrs, queryLog);

但是执行的时候报错了:运行时遇到了错误。此错误的地址为 0x663af09d,在线程 0x16c0 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。

 

请问,我在C#中声明的方法对吗?如果声明的参数没有问题,那我封送结构体数组有问题吗?

由于我是第一次处理这种平台调用的问题,所以找了好几天的资料都没有解决好,在这里,我希望能得到各位的帮助。谢谢!

ljcheibao的主页 ljcheibao | 初学一级 | 园豆:132
提问于:2013-04-25 11:32
< >
分享
最佳答案
0

C++ H 头文件  在c#中要封装成Stuct  还有C++里的一些类型 要注意哈。IntPtr 对应指针 Marshal 类库中有很多方法。。查查帮助文档。、。

收获园豆:20
在 水 一 方 | 小虾三级 |园豆:1097 | 2013-04-25 11:43

你好,你能给我详细的解答吗?

这个问题查了好久了,对于传递结构体数组的,网上提供的几种都试过了,还是报这个错误。至于C++跟C#中的类型,我也对了,现在感觉应该就错在结构体数组传递上。

 

另外还有点很奇怪的问题,就是我读取10条数据,没有报错的,读取11条就报这个错误了。

ljcheibao | 园豆:132 (初学一级) | 2013-04-25 12:40
其他回答(2)
0

问题解决了嘛,也遇到了不知道什么原因啊

vendanner | 园豆:202 (菜鸟二级) | 2016-06-12 17:44
0

遇到了同样的问题,希望能指教一下

JaydenLuo | 园豆:174 (初学一级) | 2019-01-14 11:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册