手头有个C++的DLL,是公司的一个远程通话功能组件。长久以来,这个DLL对外只有三个操作接口。而从合理的角度来说,这个DLL本应再提供一些回调接口或事件之类的东西,用于在通话状态被动改变时通知外层应用程序。不过银行里的规矩多多,不能用ActiveX;而使用回调,却又似不那么的稳定,尤其在与C#交互时。所以才一直就这么用着。
直到最近,外层应用程序的开发人员提意见抱怨这个DLL。于是,一狠心,决定向这个DLL添加回调的支持。虽然不能确定之前使用回调不稳定的问题在哪,但现有资料和之前自己单独写的测试却都表明C#向C++传递的回调是可以正常工作的。因此,必定是这个DLL的什么地方存在错误才会不稳定,大不了搭上一个周末的时间,总应该能解决吧。
一般来说,实现回调的要点就两点:
1 回调应加上WINAPI或CALL关键字,以声明其调用方式;
2 注意参数类型尤其是长度,在C++和C#中的声明要一致;避免使用指针和引用类型。
由于之前已经单独测试过,所以就差在DLL中实战演练了。花了一天时间,根据他们的要求改好了程序。为了避免遇到传说中的住在迷宫里的那个会吃迷路的人的魔鬼。其间还打了几针预防针,先在定义回调时先排除了任何字符参数,只用整数;然后去掉了之前的那个中间DLL。原来的核心DLL是MFC扩展动态链接库,不能直接用在C#中,所以又在外边套了个正规DLL。虽然间接调用DLL很正常,但让结构更简单,总没有坏处。
一切妥当,开始调试,改掉几个小问题后,发现程序竟然正常的跑起来了,回调的输出欢快的显示到屏幕上了。又各式各样的环境各测了几遍,依然OK,看来这次运气不差,哈。接下来打包,写接口和回调说明文档,画状态图。
在发出去前,想起来又改了改一些调试和日志信息,然后又神经质的测试了一把。事后证明,这是一个让人后悔也庆幸的动作。因为,这次遇到Demo的老兄Demon了,哎,怎一个惨字了得
幸亏本命年的我早有时刻面对打击的觉悟,早前没有得意忘形,要不这下心情落差大去了。额,不过,来就来吧,有周末两天做后盾,不信搞不定你。
看看Demon老兄说了些啥:SYSTEMWINDOWSFORMSNIDLL 0xC0000005 access violation。
完全摸不着头脑,只能慢慢来了。
先检查了一遍DLL程序,应该没有问题,所有的回调也都是在主线程上触发的,应该跟线程也没有关系。
再来确定到底是C++ DLL的还是C# EXE的问题,把DLL和EXE在DEBUG和Release下各编译了一份,然后组合运行了一下,发现当且仅当使用EXE的Release版程序时,会出现该异常。那么,就应该是C#程序的问题了。
这只是一个非常简单的示例,实在想不明白代码可能会有什么问题。而且还是Debug正常,Release异常。先改改编译选项试试,把Optimze Code关了试试,问题照旧;再把Define Debug constant开了,这就跟Debug版本的编译选项完全一样了,还是不行。看来此路不通了。
看看Google同学有没有遇到过这样的问题,把Demon老兄说的搜了一下,结果没有相关资料…看来这下有得头疼了。
忽然想起似乎刚才DLL和EXE组合测试的时刻似乎出过一个挺不寻常的提示。再去找找看,发现Debug版的DLL和Release版的EXE一起运行会有这样的提示:
File: i386\chkespc
Line: 42
The value of ESP was not properly saved across a function call This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention
再搜索一下,这次倒有不少同样不幸的人,不过正如那句话“不幸的人各有各的不幸”,他们的原因似乎跟我的情况扯不上啥关系。
这下没招了,再求助Baidu一下,看看大家用C++回调C#代码都遇到些啥情况。结果试了好几个关键字,都一无所获,正当我感觉鸭梨很大的时候,突然间,用关键字“C++ C# 回调 委托”搜到了一个有点意思的帖子 C#处理C++库回调报错_非托管代码传递委托被垃圾回收,虽然这位老兄什么都没说明,不过贴上来的异常内容很特别:
检测到 CallbackOnCollectedDelegate
Message: 对“HBVideoParser!VideocommVideoHBHBSDK+SrcDataParseCBHandler::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
向C++传递的委托对象回垃圾回收了,导致回调时异常?感觉有点怪怪,不过死马当活马医吧,改Demo,传了一个全局委托对象给DLL,再测试~哈,回调输出又欢快滴出来了~
看来果真如此了,确认一下,改回原来的传递临时对象的方式,在Demo的Main函数里加个异常捕获,发现确实异常会传递到此处,内容则是“Object reference not set to an instance of an object”。虽然与上述的不一致,不过应该就是一回事啦。
现在想想,这也不难理解。C#中通过引用计数来判断对象是否可被回收,在Demo中,创建的临时委托对象只是被临时使用了一下,没有任何引用,虽然在C++ DLL中保存了,但俨然那已经不属于Demo的范围了。因此被垃圾回收很正常。
再想到之前自己单独写的测试似乎并没有发现这样的问题,那又是为什么呢?难道因为程序占用内在太少还没来得及进行垃圾回收操作?再去翻出来,点住调用按钮不放,果然,在输出三四十条信息之后程序异常了。
奔驰GLA ( 查成交价 | 车型详解 ) es p按钮在中控台空调屏幕的下方,车辆默认是开启ESP功能的,按下该按钮关闭功能。ESP的全称是E le ct ronic Stability Program,我们常称之为车身电子稳定控制系统。是汽车防抱死制动系统(ABS)和牵引力控制系统(TCS)功能的进一步扩展,也是属于汽车主动安全系统的一部分。
ESP主要由传感器、执行器和电子控制单元(ECU)三大部分组成,传感器一般包括轮速传感器、方向盘转角传感器、侧向加速度传感器、横摆角速度传感器、制动主缸压力传感器等,执行器一般包括传统制动系统(真空助力器、管路和制动器)、液压调节器等,而电子控制单元与发动机管理系统联动,可对发动机动力输出进行干预和调整。
ESP主要对车辆纵向和横向稳定性进行控制,保证车辆按照驾驶员的意识行驶。在汽车制动情况下轮胎即将抱死时,车身电子稳定系统会采用“机械点刹”的形式在1秒钟内进行上白次的制动,使车辆在完成全力制动时仍然可以保持通过方向盘来控制车辆行驶的方向,这一点跟ABS的功能有异曲同工之妙。(图/文/摄: 罗婷1) @2019
ESP32-C3首先它是一款安全稳定、低功耗、低成本的物联网芯片,搭载 RISC-V 32 位单核处理器,支持 24 GHz Wi-Fi 和 Bluetooth LE 50。为物联网产品提供行业领先的射频性能、完善的安全机制和丰富的内存资源。
ESP32-C3 对 Wi-Fi 和 Bluetooth LE 50 的双重支持降低了设备配网难度,适用于广泛的物联网应用场景。
丰田 威驰 ( 查成交价 | 车型详解 )如何关闭 es p? 汽车网我为您来解答。
丰田威驰如何关闭esp呢?按下ESP的按钮即可注意的是,威驰只有中高配才有配备ESP哦,选择的时候要看清配置表,选出自己需要的。车身电子稳定系统(E le ct ronic Stability Program,简称ESP),是博世(Bo sc h)公司的专利。一般汽车的ESP是默认开启的有些能够手动关闭,着机自动开启。还有的车是不能完全关闭的。因为是有关于安全问题的,汽车厂 商 在标定的时候也不敢擅作主张。不然这个担的责任就大了。威驰的ESP开关的位置在副驾驶座椅边上。
ESP系统实际是一种牵引力控制系统,与其他牵引力控制系统比较,ESP不但控制驱动轮,而且可控制从动轮。如后轮驱动汽车常出现的转向过多情况,此时后轮失控而甩尾,ESP便会刹慢外侧的前轮来稳定车子;在转向过少时,为了校正循迹方向,ESP则会刹慢内后轮,从而校正行驶方向。从而一定程度上保障行车安全。
总评:威驰(Vios)是丰田专门为亚洲市场设计开发的家庭入门级车型,以 NBC 的平台为基础,在加长轴距后,在小型车平台上开发的威驰几乎达到了紧凑型轿车的水平。威驰车身造型源自于丰田的新 世纪 设计主题“VIBRANT CLA RITY”(活力清爽),极富动感又不失强悍;车内空间精良考究,集高档设计与尖端科技于一身。正是这些特点在高层次上的统一创造出了这一新世纪的丰田轿车。
以上就是汽车网我整理的关于“丰田威驰如何关闭esp”相关知识内容,希望能对您有所帮助。
@2019欢迎分享,转载请注明来源:品搜搜测评网