代码境遇的难点总计,Windbg使用表达书

近年在开采服务后台的时候,使用c#调用了四个c++编写的dll,时期遇到了一多种的难题,经过一番竭力最终都相继消除了,在此做个小结,方便今后参考,毕竟这么些难题也都以很普及的,主要有以下难点:

前不久在支付服务后台的时候,使用c#调用了三个c++编写的dll,期间蒙受了壹各个的主题材料,经过一番竭力最终都逐项化解了,在此做个小结,方便未来参考,终归这么些难点也皆以很布满的,重要有以下难点:

C#调用Java

将jar转换为dll
切切实实步骤 :下载三个 IKVM 配置好情况变量 具体操作如下
1、将曾经编写翻译后的java中Class文件进行打包;打包命令JALX570

  1. 此地
    java的全部类必须放在1个Package中,不要使用缺省的包,C#会找不到类之间的调用(C#貎似无法引用其余dll里的默许namespace里边的始末,所以java文件必须注脚包,以便被转变来命名空间。其它,因为
    java中暗中认可访问权限的主意会被转变来internal方法,所以在java中必须将这几个艺术显式地宣称为public),须要和睦建,笔者用的是eclipse,写完程序直接导出成jar文件。

除此以外未来这么些版本好像不辅助Java
图形分界面,反正小编调节和测试时,一旦new二个控件,C#就说此办法未被落成如何的。

  1. 也能够选取命令:jar cvf test.jar -C com/ .

当中test.jar为要扭转的jar包;com/ .
为钦命的当前目录下的文件夹,该文件夹包含子文件夹及class文件;

二、到IKVM官方网站下载IKVM供给的机件
http://www.ikvm.net/

ikvmbin-0.44.0.5.zip

叁、设置路线

解压ikvmbin-0.44.0.5.zip
,并将%IKVM_HOME%\bin添加到path中。此处的%IKVM_HOME%是指解压后ikvm的主目录。

肆、将java的jar包转变为.dll控件

运用的下令:ikvmc -out:IKVM.dll test.jar (整个操作那些是不可缺少的。)

内部IKVM.dll为就要变化的.dll控件文件名;test.jar(尽量加多上文件的路子)为事前打包好的jar包文件。(写的时候尽量添Gavin件的门道名称,便于搜索生成后的dll文件

当今dll文件已经打响了,不过前边还有使用这么些dll在抬高到C#品类中运作的时候恐怕会报错。那些错误正是缺少一些IKVMxxxx.dll文件,这一个文件都在ikvm-0.4陆.0.壹\bin
文件下得以找到。

五、在C#品类中增添所需的控件

一、新建一个C#.NET项目,首先增加一下须要的DLLs (references中Add
reference,然后Browse找到dll)

%IKVM_HOME%\bin\IKVM.OpenJDK.Core.dll

%IKVM_HOME%\bin\IKVM.Runtime.dll

%IKVM_HOME%\bin\IKVM.Runtime.JNI.dll

2、加多已成形的.dll文件

将事先生成好的.dll文件加载到C#项目中

六、测试

在C#类型中使用java类,其格局同java。首先用using 包名,那样本事找到类

术语、缩略语

  • 花色对照难点
  • 内存释放难点
  • 本子难点(x八6与x6四)
  • 编写翻译难题(静态与动态)
  • 能源加载难点
  • 越发捕获与主题素材一定
  • vs实时调节和测试难题
  • 花色对照难题
  • 内部存款和储蓄器释放难点
  • 本子难点(x八陆与x6四)
  • 编译难点(静态与动态)
  • 能源加载难题
  • 相当捕获与主题材料一定
  • vs实时调试难题

Java使用jna调用c#中的dll

一、原理表明:
因为c#代码是托管到.net平台上的,所以java不可能一向调用c#代码,于是引入C++中间件,c++项目能够安装项目为clr公共运行时,从而通过引用的艺术调用c#对应措施。而jna是足以一向调用c++生成的dll的,于是大致流程就走通了。c++调用写好的c#dll,java再调用c++生成的dll中间件,大概流程就是这样了,但是里面有为数不少坑,上边小编会细说。

贰、运维平台:

  • 系统:Windows 10 x64

  • 开垦工具:Visual Studio
    2016/20一7(小编台式机和百货店Computer安装差别版本,笔者都有落到实处过)
    MyEclipse201四

  • SDK:jdk-x八六、jdk-x6四(dll分为x8六和x6四平台,和jdk的版本要相应,同壹台Computer装多个本子的jdk比较烦,笔者利用的是系统布署jdk3一位调试三11个人dll,然后myeclipse自带六十一个人jdk调节和测试陆拾3人dll)

三、盘算职业:

一、首先希图上述运营平台,建议选拔和系统位数1致的jdk(安装vs、myeclipse或eclipse或sts);

2、下载jna.jar
:JNA下载
(下载jna-4.4.0.jar 和 jna-platform-4.4.0),也可以
代码境遇的难点总计,Windbg使用表达书。本地下载

四、开始CODE

1. 生成c#DLL

(1)以管理人格局运行vs(项目涉嫌到注册com组件,必须以管理人运营技艺成就),新建c#项目

美高梅开户网址 1

(二)设置c#项目

第叁,右键刚刚新建的Invoke项目,点击属性。

美高梅开户网址 2

继续设置项目性质。

美高梅开户网址 3

记得保存。

下一场新建须求被调用的CSharp类代码。那里大家新建一些归纳的主意,为了演示效果大家独家对int、string、bool举行操作。如图:

美高梅开户网址 4

然后右键项目,点击生成。

美高梅开户网址 5

首先步,完毕,干得出彩。

2. 生成c++中间件

(一)新建c++项目并设置属性

美高梅开户网址 6

美高梅开户网址 7

美高梅开户网址 8

项目新建成功,右键项目,采用属性。

美高梅开户网址 9

美高梅开户网址 10

image

美高梅开户网址,(二)书写c++代码

添加cpp文件

美高梅开户网址 11

美高梅开户网址 12

编辑cpp文件

好了,c++和c#整整工作达成,右键生成。

美高梅开户网址 13

复制下dll生成文件全名,1会儿java里面用。

五、编写java代码

一. 新建java project
,注意接纳和dll平台1致的jdk。然后将在此以前下载的七个jna的jar加载到花色里面,如图:

美高梅开户网址 14

2. 开始写java 代码

接下来我们运转:

美高梅开户网址 15

哦豁,报错了【无效的内部存储器访问】,因为java找到了c++dll,但是没找到c#的dll,在那之中c++dll大家写的全方位径名,能够平素找到,那么c#的dll怎么找呢。答案是将c#的dll复制到jdk的bin目录下,jvm就能找到了。

如图我们将Invoke.dll复制到jdk的bin目录下:

美高梅开户网址 16

下一场再运维:

美高梅开户网址 17

nice!对于常用类型中的int、string、boolean都得以顺遂传递了,事实上别的体系的也足以兑现,只要依据分歧语言之间的品种对应关系就可以了,具体的花色涉及足以百度。

陆、注意事项

1. java报错:Exception in thread “main” java.lang.Error: Invalid
memory access

莫不原因:

  • c#dll未有复制到jdk的bin目录;

  • java和c++之间数据类型不对应;

2. java报错:Exception in thread “main”
java.lang.UnsatisfiedLinkError: Unable to load library ‘D:\vs
workplace\X86InvokeTest\Release\X86CPPDlls’: Native library
(win32-x86/D:\vs workplace\X86InvokeTest\Release\X86CPPDlls.dll) not
found in resource path
([file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/bin/,
file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-4.4.0.jar,
file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-platform-4.4.0.jar])

也许原因:

  • c++dll路线不科学,提议做test时用绝对路线,那样你在c++项目编写翻译过后并非拷贝便得以在java程序里面一直调用;

  • jdk的平台和c++项目标平台不相配,jdk是三12人那么c++dll一定也是三十七人的,67人也一律;

3.
windows61个人下编写翻译的三1三位dll测试失利,一时半刻不知底是还是不是6拾三人系统的原因,由于本人Computer虚拟机没有装上,就不曾去三拾伍位系统上测试了。

windbg 

品种对照难题

c#调用c++方法时,首先要在类中定义一个与c++方法对应的外部方法,因为该方法是用C#言语定义的,那么早晚要清淤楚C#项目与c++类型怎么着对应,不然会导致调用退步,关于这几个难题莫过于不算什么难题,互连网有广大品类对照的小说,都有很详细的相应列表,用的时候参考一下就足以了。还是能够运用工具,自动依照c++方法签字生成对应的C#
import方法签字,参考P/Invoke Interop
Assistant。可是有三个难题或许要小心的,在x八六格局下c#中的int对应c++中的int,而在x64模式下C#中的int是对应c++中的long,就那样1个细小的变量类型,在不经意间恐怕就会导致c++代码出错。

还有1个标题是:托管的 PInvoke 签名与非托管的目标签名不匹配,可以在C#代码的点子性格上丰裕CallingConvention.Cdecl。如下所示:

[DllImport("dllname.dll", CharSet = CharSet.Ansi, EntryPoint = "methodname", CallingConvention = CallingConvention.Cdecl)]

项目对照难题

c#调用c++方法时,首先要在类中定义2个与c++方法对应的外表方法,因为该方法是用C#语言定义的,那么一定要搞清楚C#类型与c++类型如何对应,不然会形成调用失败,关于那一个标题实际上不算什么难题,英特网有不少项目对照的稿子,都有很详细的呼应列表,用的时候参考一下就能够了。还足以选取工具,自动依据c++方法签字生成对应的C#
import方法签字,参考P/Invoke Interop
Assistant。可是有贰个标题照旧要小心的,在x八陆格局下c#中的int对应c++中的int,而在x64模式下C#中的int是对应c++中的long,如同此七个微小的变量类型,在不经意间只怕就会变成c++代码出错。

再有多少个主题素材是:托管的 PInvoke 签名与非托管的目标签名不匹配,可以在C#代码的法门性子上增多CallingConvention.Cdecl。如下所示:

[DllImport("dllname.dll", CharSet = CharSet.Ansi, EntryPoint = "methodname", CallingConvention = CallingConvention.Cdecl)]

windows平台下,庞大的用户态和内核态调节和测试工具。

内部存款和储蓄器释放难点

由于那一个主题材料时常蒙受,并且只要不能够一挥而就的话料定不会再思量动用该dll了,那是三个可用性的主题素材。所以小编在调用c++方法的时候,经常都会先批量跑一边,通过日记记录下每调用壹回艺术后,当前进度所占有的内部存款和储蓄器大小,那样在运维壹段时间现在,就能很通晓的看来内部存储器是还是不是持续加强,倘诺是的话就需求和编排该dll的同事实行关联,给他们提供测试数据,确认发生难点的因由。有时正是C++中的方法开始展览了内部存款和储蓄器释放,并且在c++测试代码中曾经未有内部存款和储蓄器增进难点了,可是在C#中调用的时候内部存储器照旧会不断升高,该难点可能跟使用的现象有关,作者那里是因为调用了三个回到char
*花色的c++方法,笔者一贯用C#中的字符串类型的一个变量接收了,结果开采内部存款和储蓄器总是刑释不了,后来让同事把c++的办法更动了1晃参数,然后在C#有效StringBuilder类型的变量作为参数传入c++方法中来接受该办法的结果,那样该内存难题就化解了。

C#
// 在C#中声明与C++方法对应的dllimport方法
[DllImport("dllname.dll", CharSet = CharSet.Ansi, EntryPoint = "Handle", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CPPMethod(string content,StringBuilder result);

// 该变量用来接收c++方法的处理结果,作为传出参数传入c++方法,在构造的时候必须明确指定大小
// 如果不指定或者指定的大小不足,会导致c++方法出现空间分配不够的异常
StringBuilder resultSB = new StringBuilder(length);
string cppParam = "some content";
bool isSuccess = CPPMethod(cppParam,resultSB);  // CPPMethod是与C++方法对应的dllimport方法

C++ 
// C++中的DLL函数原型,即:C#中要调用的方法,此处不再返回char *类型的结果,而是将结果放到传出参数result中
extern "C" __declspec(dllexport) bool Handle(char* content, char* result);  // result为传出参数

局地时候内存难题是纯粹出于c++代码导致的,一般蒙受内部存储器问题,作者会用c++的测试工程再跑1遍,看看是或不是仍有该难题,假如是注脚真是c++的bug了,能够布告同事去修改bug了。

内存难点偶尔并不会反映的不得了引人注目,那亟需大家越来越细致的体察日志并发掘导致难题的的确原因。笔者在此之前境遇该地方的2个标题,刚起始内部存款和储蓄器上涨的幅度13分理解,经过反复与开销该dll的同事联系后,难题已经消除的大半了,可是大量测试后开掘内部存储器依旧会有一些水涨船高,就算大幅极小,但第陆感告诉笔者当中必有神奇,那假若上线跑个几天岂不是还得爆,后来作者把每三回调用c++方法后当前进程占用的内部存款和储蓄器输出到文件中,经过仔细察看,开采绝超过五分之三文书(文件内容要传播c++方法中张开始拍录卖)都没难题,内部存款和储蓄器都很牢固,不过有相当的小部分文件在传唱c++方法后,会促成内部存款和储蓄器相比较其余文件有八个可想而知的坚实,看来难点是出现在这几个文件中,随后把这几个文件单独放在壹块儿开始展览巡回调用,内部存款和储蓄器一下子就大幅度增进了,前边就绝不说了,难题理所当然消除了。因而,要保持记日志的良好习惯,哪怕是在测试工程中

内部存储器释放难点

鉴于这些难点经常碰到,并且只要不可能化解的话分明不会再考虑选用该dll了,这是3个可用性的难点。所以本人在调用c++方法的时候,日常都会先批量跑1边,通过日记记录下每调用3次艺术后,当前历程所占用的内部存款和储蓄器大小,那样在运作1段时间未来,就能很通晓的看到内部存储器是还是不是持续抓牢,若是是的话就必要和编排该dll的同事进行沟通,给他俩提供测试数据,确认发生难题的来由。有时即便C++中的方法进行了内部存款和储蓄器释放,并且在c++测试代码中已经远非内存增加难题了,不过在C#中调用的时候内存仍然会不断巩固,该难题也许跟使用的现象有关,作者这边是因为调用了贰个回到char
*花色的c++方法,笔者平素用C#中的字符串类型的四个变量接收了,结果开采内部存款和储蓄器总是假释不了,后来让同事把c++的主意更动了刹那间参数,然后在C#实惠StringBuilder类型的变量作为参数字传送入c++方法中来接受该格局的结果,那样该内部存款和储蓄器难点就化解了。

C#
// 在C#中声明与C++方法对应的dllimport方法
[DllImport("dllname.dll", CharSet = CharSet.Ansi, EntryPoint = "Handle", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CPPMethod(string content,StringBuilder result);

// 该变量用来接收c++方法的处理结果,作为传出参数传入c++方法,在构造的时候必须明确指定大小
// 如果不指定或者指定的大小不足,会导致c++方法出现空间分配不够的异常
StringBuilder resultSB = new StringBuilder(length);
string cppParam = "some content";
bool isSuccess = CPPMethod(cppParam,resultSB);  // CPPMethod是与C++方法对应的dllimport方法

C++ 
// C++中的DLL函数原型,即:C#中要调用的方法,此处不再返回char *类型的结果,而是将结果放到传出参数result中
extern "C" __declspec(dllexport) bool Handle(char* content, char* result);  // result为传出参数

有的时候内部存款和储蓄器难点是彻头彻尾出于c++代码导致的,一般境遇内部存款和储蓄器难题,笔者会用c++的测试工程再跑一回,看看是不是仍有该难题,即便是验证真是c++的bug了,能够文告同事去修改bug了。

内部存款和储蓄器难题偶尔并不会反映的不胜显眼,那亟需我们越来越细致的体察日志并发掘变成难题的的确原因。作者前面境遇该地点的八个标题,刚开头内部存款和储蓄器上涨的幅度1二分通晓,经过反复与付出该dll的同事联系后,难点早就减轻的大半了,不过大批量测试后开采内部存款和储蓄器依然会有一些上涨,即便大幅度十分小,但第四感告诉小编个中必有蹊跷,那假使上线跑个几天岂不是还得爆,后来作者把每3遍调用c++方法后当前进度占用的内部存款和储蓄器输出到文件中,经过细致察看,发掘绝超过一半文书(文件内容要传播c++方法中展开拍卖)都没难题,内部存款和储蓄器都很稳固,可是有比异常的小部分文书在传唱c++方法后,会导致内部存款和储蓄器比较其余文件有一个明显的巩固,看来难点是出现在这一个文件中,随后把那么些文件单独放在一块儿开始展览巡回调用,内存一下子就小幅增进了,前边就绝不说了,难点理所当然消除了。因而,要保持记日志的良好习惯,哪怕是在测试工程中

dmp

本子难点(x八六与x6四)

本子不兼容的话,在调节和测试时会提醒正在加载格式不正确的dll,假若采取的是3二位的c++版dll,供给把C#品类的编写翻译平台安装为x捌陆,假诺利用的是陆九人的c++版dll,则设置为any
cpu和x6四都能够,这些须要团结根据真实景况对应好就足以了。假诺程序对内部存款和储蓄器的接纳相比高,最佳将次第编写翻译为60个人,因为叁拾几个人程序对单进程的内部存款和储蓄器大小有限量,经测试最大不超过贰G。因为作者的程序刚先河选用的是三11位的c++版dll,并且在运转时须求调用这么些dll加载许多财富,加载完这么些财富进程占用的内存就大致快2G了,所以总会莫明其妙的崩掉,以至在加载的历程中就径直崩掉了,当时预见到是3壹个人的难题,后来让同事将dll重新编写翻译为63位后就从未这么些主题素材了。能够透过dumpbin命令决断一个dll是三十二个人依然60位,展开vs开荒人士命令提醒,输入:dumpbin /headers 你的dll路径,例如:dumpbin /headers d:\test.dll,如下图所示:

美高梅开户网址 18

倘使是3几人dll,红框那里会突显
美高梅开户网址 19

此处有一个地点须求注意,私下认可asp.net项目在调整时会运营在三十二位下的iisexpress进程中,假设您的种类是陆拾4个人的,那么需求在VS元帅iisexpress配置为六十六人形式,如下图所示:

美高梅开户网址 20

本子难点(x8陆与x6四)

本子不相配的话,在调解时会提示正在加载格式不正确的dll,假如选取的是34位的c++版dll,供给把C#类型的编写翻译平台安装为x八六,固然选择的是六十个人的c++版dll,则设置为any
cpu和x6四都得以,那么些要求本身依照实情对应好就能够了。假使程序对内部存款和储蓄器的运用相比较高,最佳将顺序编写翻译为61位,因为三14个人程序对单进度的内部存款和储蓄器大小有限制,经测试最大不超越2G。因为自个儿的先后刚早先运用的是三十七位的c++版dll,并且在运作时索要调用那一个dll加载许多财富,加载完那一个财富进度占用的内部存款和储蓄器就基本上快2G了,所以总会莫明其妙的崩掉,以至在加载的经过中就一向崩掉了,当时预见到是三11人的主题材料,后来让同事将dll重新编写翻译为611人后就从未有过那么些标题了。能够由此dumpbin命令剖断多个dll是3拾1个人还是陆11个人,展开vs开辟职员命令提醒,输入:dumpbin /headers 你的dll路径,例如:dumpbin /headers d:\test.dll,如下图所示:

美高梅开户网址 21

假定是33位dll,红框那里会显得
美高梅开户网址 22

此间有一个地点必要留意,私下认可asp.net项目在调节和测试时会运营在3九人下的iisexpress进度中,如若你的品种是陆11位的,那么要求在VS中校iisexpress配置为陆九人情势,如下图所示:

美高梅开户网址 23

内部存款和储蓄器影象文件,一般是系统错误发生的文件。

编写翻译难题(静态编写翻译与动态编写翻译)

本条主题材料在运行时有时候会唤醒dll加载不成功,那些标题在分裂的计算机上会有例外的反映,有的存在那么些主题素材,有的就运营平常。而本人本机就属于常规的,安顿的服务器属于出标题的。出现这几个难点后,在肯定代码不易后,笔者用depends.exe以此工具查看了弹指间造成难题的不行c++版的dll都依附什么程序集,在出标题标机器上会提醒有局地重视的dll不设有,而那些dll在运作平常的机器上是存在的。下图褐绿框中的为有个别机器上或者会缺点和失误的dll:

美高梅开户网址 24

万1缺点和失误相关dll,该条目的左侧会突显出贰个色情的问号。那些标题得以应用静态编写翻译实行化解,关于怎么样是静态编译能够活动百度,同理可得正是将先后所依据的dll编写翻译到程序聚焦,这样就是其余机器不设有那几个dll也得以平常运转了,静态编写翻译能够在vs的项目性质中张开设置

美高梅开户网址 25

默认是多线程 DLL(/MD),即:动态编写翻译,那里改变为
多线程(/MT),即:静态编译。

刚刚的布局只可以化解不够MSVCP120.DLL和MSVC奥迪Q5120.DLL那一类主题材料,对于贫乏MFC相关的dll,还要经过下边的配备:

美高梅开户网址 26

默认是使用标准Windows库,这里改为在静态库中使用MFC

编写翻译难题(静态编写翻译与动态编写翻译)

本条标题在运转时有时候会提醒dll加载不成功,这一个问题在差异的计算机上会有分化的反映,有的存在这一个标题,有的就运营如常。而自己本机就属于常规的,计划的服务器属于出难题的。现身那几个题材后,在承认代码不易后,笔者用depends.exe其壹工具查看了刹那间导致难点的丰富c++版的dll都信赖什么程序集,在出标题标机器上会提醒有壹对依据的dll不设有,而那些dll在运营常常的机械上是存在的。下图墨蓝框中的为一些机器上或者会缺点和失误的dll:

美高梅开户网址 27

壹旦缺点和失误相关dll,该条目款项的左手会展现出2个香艳的问号。这么些难点得以行使静态编写翻译举行化解,关于怎么样是静态编写翻译能够自行百度,同理可得正是将次第所依附的dll编写翻译到程序聚集,那样固然别的机器不设有那么些dll也足以平常运作了,静态编写翻译能够在vs的类型性质中实行设置

美高梅开户网址 28

默认是多线程 DLL(/MD),即:动态编写翻译,那里退换为
多线程(/MT),即:静态编写翻译。

刚刚的安顿只可以消除不够MSVCP120.DLL和MSVC君越120.DLL那一类主题材料,对于贫乏MFC相关的dll,还要经过下边包车型大巴布局:

美高梅开户网址 29

默认是使用标准Windows库,那里改为在静态库中使用MFC

Pdb

财富加载难题(相对路径与相对路径,dll中又调用其余dll加载能源)

本条难题绝对比较隐蔽,出现时不会抛出十二分,只可以通过c++方法重回的情况码来推断方式实行是不是成功,要不是在那里放了一个断点,特意看了一下,恐怕就遗漏这几个主题材料了。

场景是如此的:
自家在webservice中调用c++版dll中的2个初阶化方法,该方法会加载一些财富文件,小编在vs中调理实行的时候没难题,发表之后居然无法加载能源,貌似是路线难题,作者把资源文件放到w三wp.exe的根目录下倒是可以成功加载,放在别的目录中就相当,境遇那一个标题首先想到的或是是财富随地的目录权限不够导致iis无法平常加载,因为事先有个一样的题目就是这么,但这一次将能源到处的目录更换为伊夫ryone用户的一点一滴调节权限照旧那多少个,并且该难题只现出在b/s项目中,c/s项目尚未这几个标题。并且该目录中存放了许多能源文件,有有些个c++版的dll都急需从此间加载,其余多少个都没难点,就那3个dll不行,看来不是权力的难点。那时候又想是或不是相对路线的主题材料,那小编改成相对路线吧,结果难点还是,后来在本领群里有个大腕说试试Directory.SetCurrentDirectory,赶紧修改代码,测试了弹指间真的好使了。代码如下:

// 保存当前工作目录
string currWorkPath = Directory.GetCurrentDirectory();
// 切换当前工作目录
Directory.SetCurrentDirectory(resourcePath);
// 初始化进行资源加载
Init(resourcePath);  // 这里要注意,使用了SetCurrentDirectory方法后,resourcePath要用相对路径
// 还原当前工作目录
Directory.SetCurrentDirectory(currWorkPath);

如注释所示,使用SetCurrentDirectory切换了当前职业目录后,方法中所用的门路要改为相对路线,一初阶本身用的是相对路线,居然照旧不可能加载。

新兴察觉了该难题的原由,在应用的dll中又调用其它3个dll实行财富加载,或然这么会形成那多少个直接调用的dll出现路线难点,所以出现财富加载退步。

财富加载难点(相对路线与相对路线,dll中又调用别的dll加载财富)

这些标题绝比较较隐蔽,出现时不会抛出特别,只可以通过c++方法重回的景况码来判定格局施行是或不是中标,要不是在那边放了二个断点,特意看了一晃,或许就遗漏那个主题素材了。

气象是那样的:
自己在webservice中调用c++版dll中的二个伊始化方法,该方法会加载一些财富文件,笔者在vs中调养推行的时候没难题,揭橥之后居然不能加载财富,貌似是路线难题,小编把财富文件放到w三wp.exe的根目录下倒是能够成功加载,放在其余目录中就老大,蒙受这么些标题首先想到的或是是能源四处的目录权限不够导致iis不能正常加载,因为事先有个一样的标题就是那般,但此次将能源随处的目录改动为伊芙ryone用户的完全调控权限依然那四个,并且该难点只出现在b/s项目中,c/s项目尚未这几个难题。并且该目录中存放了诸多财富文件,有几许个c++版的dll都供给从那边加载,其余多少个都没难题,就那四个dll不行,看来不是权力的难题。那时候又想是还是不是相对路线的主题素材,那笔者改成相对路径吧,结果难点还是,后来在手艺群里有个大拿说试试Directory.SetCurrentDirectory,赶紧修改代码,测试了一晃确实好使了。代码如下:

// 保存当前工作目录
string currWorkPath = Directory.GetCurrentDirectory();
// 切换当前工作目录
Directory.SetCurrentDirectory(resourcePath);
// 初始化进行资源加载
Init(resourcePath);  // 这里要注意,使用了SetCurrentDirectory方法后,resourcePath要用相对路径
// 还原当前工作目录
Directory.SetCurrentDirectory(currWorkPath);

如注释所示,使用SetCurrentDirectory切换了当前职业目录后,方法中所用的路径要改为相对路线,一初步本人用的是相对路线,居然照旧不能加载。

后来意识了该问题的原由,在运用的dll中又调用其余多少个dll实行财富加载,只怕这么会招致那个直接调用的dll出现路线难题,所以出现财富加载失利。

先后数据库文件。

卓殊捕获与难题一定

关于那些捕获,尽管在艺术中增加了特点HandleProcessCorruptedStateExceptionsSecurityCritical但要么捕获不到c++中的万分,原因恐怕是c++在遇见一些非常时会产生程序直接退出,那样在C#中就自然捕获不到了,所以照旧尽量保证c++代码的健壮性。
如果在c#中调用了多少个c++版dll中的方法,因为有时候捕获不到不行,很难通过正规方法找到标题的原因,c++方法中假诺出现卓殊恐怕会一向形成进度退出了,那时能够借助操作系统中的事件查看器来找寻越发是来自哪个dll,同时在原始代码中注释掉那段调用该c++方法的代码,大概mock一个措施调用,保险该段代码无特别,然后再张开测试,假设无不胜,那么一旦消除了要命c++方法的难点就可以,要是还有十分那么正是任何dll的主题素材,然后能够编写制定测试代码单独测试曾经出难点的dll中的方法。异常捕获+事件查看器+日志能够支持开采者开掘先后的超越八分之四标题与原因。

特出捕获与主题材料一定

关于充足捕获,就算在措施中增多了特点HandleProcessCorruptedStateExceptionsSecurityCritical但依旧捕获不到c++中的分外,原因大概是c++在遇见一些卓殊时会形成程序直接退出,那样在C#中就自然捕获不到了,所以还是尽量保障c++代码的健壮性。
如果在c#中调用了两个c++版dll中的方法,因为偶然捕获不到12分,很难通过正常办法找到难点的因由,c++方法中假若出现卓殊大概会直接产生进程退出了,那时能够注重操作系统中的事件查看器来找寻至极是发源哪个dll,同时在原有代码中注释掉那段调用该c++方法的代码,可能mock1个方法调用,保险该段代码无越发,然后再开展测试,若是无特别,那么一旦化解了那么些c++方法的主题材料就可以,如若还有尤其那么正是其余dll的标题,然后能够编写测试代码单独测试曾经出难题的dll中的方法。异常捕获+事件查看器+日志能够帮忙开辟者发掘先后的很多标题与原因。

Symbol

别的主题材料

任何难点

标志文件(Symbol
Files)是1个数据音讯文件,它包涵了应用程序二进制文件(比方:EXE、DLL等)调节和测试音信

1、0X一A截断全文的主题素材

其一是c++代码读取文件时恐怕会遭逢的1个难点,即使在调解有些难题的经过中发觉了这一个状态,但新兴经开辟dll的同事说难题的因由不是以此,那里就仅此记录一下呢,ifstream in("test.txt",'b');如此丰硕第一个参数就不会截断了。

一、0X一A截断全文的难题

本条是c++代码读取文件时可能会超过的2个标题,即使在调解有些难题的进度中窥见了那么些场合,但后来经开拓dll的同事说难点的来头不是其壹,那里就仅此记录一下啊,ifstream in("test.txt",'b');诸如此类丰富第一个参数就不会截断了。


二、vs实时调节和测试产生iis进度一直等候的难点

两遍遇到那些难点都是在收工前面世的,当时也不知底怎么样原因,后来透过windbg看了瞬间测试程序和w3wp进度的转储文件,通过!gle -all命令开掘各种线程都在等候景况,如下图所示:

美高梅开户网址 30

iis进度也是那般,本感到是代码死锁了,不过经过!locks命令也没觉察有别的特别(关于这么些标题,能够参考
应用死锁分析,当时稍微懵,不晓得是何等导致了那种景色,后来产生一件业务让自个儿弄领悟了干吗,那是在快下班的时候,程序正好出现了2个相当(虽是万分,其实不会产生程序崩溃退出),那时服务器上弹出了2个vs实时调节和测试的唤醒窗口,小编注意到iis的cpu使用率突然就降为0,测试程序的调节台也出口了线程等待的消息,联想到后边那贰个STATUS_WAIT_0的错误音讯以及貌似死锁的图景,作者备以为大概是iis终止了独具线程,在守候vs实时调试这一个互动窗口的终结,由于一贯都以在收工后才会敞开测试程序来验证程序的安澜,所以当弹出这些互动窗口时,平素不会有人去管理,线程不会直接这么等下去,最后测试程序就淡出了,iis也无能为力再持续管理请求了,那几个互动窗口也一般消失了(为何用一般,因为笔者尚未专门去注意,只是凭印象感觉以前没见过),想到那本人点了瞬间“打消调节和测试”,程序继续往下运作了,也不再阻塞了。所以在程序运维的时候,最佳关闭VS的实时调节和测试功用,防止变成不需求的标题。进入visual
studio中,采用【工具】->【选项】,点击【调式】,在【实时】选项卡中把【本机】【脚本】【托管】多个对勾打消掉就能够了。

美高梅开户网址 31

实际上尽管实时调节和测试窗口不见了,大家也得以经过系统事件来找到一些马迹蛛丝,如下图所示,只可是很难仅凭那个事件就剖断难点的原委,因为服务器上运营了多少个w三wp实例,只可以说经过这几个场馆坚实部分经历了。

美高梅开户网址 32

其实还有1部分题材,到前几天多少记不清了,就不敢贸然凭残存的那点记念来描述了,以便形成不须求的误解。对于遇到的主题素材,某个很引人侧目,有些很隐蔽,有个别须求仔细分析,某些供给在大气测试的图景下才会发觉,那里只想说一句:测试很关键,职业需用心。

二、vs实时调节和测试形成iis进度一贯等待的主题素材

三遍境遇那些主题材料都以在收工后出现的,当时也不知晓什么原因,后来经过windbg看了一下测试程序和w3wp进程的转储文件,通过!gle -all指令开采每种线程都在等候状态,如下图所示:

美高梅开户网址 33

iis进度也是如此,本感到是代码死锁了,然则通过!locks一声令下也没发掘有其余尤其(关于那个题材,能够参考
使用死锁分析,当时不怎么懵,不知情是什么样导致了那种气象,后来时有产生壹件专门的学问让小编弄通晓了为啥,那是在快下班的时候,程序正好出现了一个百般(虽是非凡,其实不会促成程序崩溃退出),那时服务器上弹出了八个vs实时调节和测试的唤醒窗口,我留意到iis的cpu使用率突然就降为0,测试程序的调整台也出口了线程等待的新闻,联想到事先那么些STATUS_WAIT_0的错误信息以及貌似死锁的场馆,我深认为或者是iis终止了全部线程,在守候vs实时调试那一个互动窗口的完成,由于日常都以在下班后才会议及展览开测试程序来证实程序的安宁,所以当弹出这几个互动窗口时,平素不会有人去管理,线程不会平素那样等下去,最终测试程序就退出了,iis也无能为力再持续处理请求了,那几个互动窗口也相似消失了(为啥用一般,因为自个儿从未越发去留意,只是凭印象以为在此之前没见过),想到这本人点了眨眼之间间“撤废调节和测试”,程序继续往下运维了,也不再阻塞了。所以在程序运维的时候,最佳关闭VS的实时调试效率,防止导致不供给的主题素材。进入visual
studio中,选择【工具】->【选项】,点击【调式】,在【实时】选项卡中把【本机】【脚本】【托管】多个对勾取消掉就足以了。

美高梅开户网址 34

实际尽管实时调试窗口不见了,大家也能够经过系统事件来找到一些马迹蛛丝,如下图所示,只可是很难仅凭这么些事件就推断难点的案由,因为服务器上运营了七个w3wp实例,只可以说通过那么些情景加强部分经验了。

美高梅开户网址 35

事实上还有一对题材,到明日多少记不清了,就不敢贸然凭残存的这点记念来讲述了,以便产生不须求的误会。对于遭受的难题,有些很明朗,某个很隐蔽,有个别须要仔细分析,有个别需求在大气测试的气象下才会意识,那里只想说一句:测试很关键,工作需用心。

概述

Windbg是Windows平台下庞大的工具。相相比较于Visual
Studio,它是一个轻量级的调护治疗工具,所谓轻量级指的是它的安装文件大小十分的小,可是其调治成效,却比VS更为有力。它的其余3个用场是足以用来分析dump数据,仍可以调护医疗进程死锁之类的。调节和测试作用,类似于Visual
Studio,还援助命令格局。该文书档案只适用于VC++,而C#的还索要卓殊开始展览局地布局,原理大致同样。

Windbg只是叁个工具,要调节其宗旨的选取办法,和调整命令,在实施中不断完善本人的调节和测试手段。同时能够参考一下济公们的文献《Windows用户态程序高效排错》,《Windows高档调节和测试》,《软件调节和测试》


下载

Windbg使用非常常见,网络格外多的下载版本,而且文档也相比多,能够到CSDN只怕其余网址下载,帮忙浅莲灰包运行。


配置

Windbg在运用前,须求张开安顿。

壹.一景况变量

一、增添遭逢变量:_NT_SYMBOL_PATH

二、境况变量值:

C:\MyCodesSymbols;SRV*C:\MyLocalSymbols*

美高梅开户网址 36

蒙受变量配置

三、依照景况变量值,在C盘下新建文件夹:MyCodesSymbols,MyLocalSymbols那八个公文夹首要存放在windows的记号文件,也正是系统暗许的有的pdb文件,那一个文件不是系统自带的,必要安顿好链接,第2遍调节和测试的时候windbg暗中认可下载须求的缺点和失误的symbol文件。

美高梅开户网址 37

pdb 下载的公文


Windbg工具配置

标识配置Symbol File Path

C:\MyCodesSymbols;SRV*C:\MyLocalSymbols*

美高梅开户网址 38

标识配置

源码路线配置Source File Path

工具不会智能定位到对应的源码,所以要布局你的源码工程的门径,是工程文件(比方那种格式的公文:*.vcxproj)所在的路径。

美高梅开户网址 39

源码配置一

美高梅开户网址 40

源码地点


编写翻译器配置

支撑VC陆以上的Visual Studio编写翻译器,设置相关的特性

明确命令禁止优化项:

美高梅开户网址 41

取缔优化项1

美高梅开户网址 42

禁绝优化项二

浮动程序数据库文件

美高梅开户网址 43

pdb 文件


使用

工具进行利用前布署后,能够伸开职业了。那里介绍绑定进度张开调节和测试的操作步骤。


绑定进度

留神,进度要先运营再进行绑定设置,因为Attach to
Process窗口不会像职责管理器一样实时刷新进度。选中进程名称,点击Ok确认。

美高梅开户网址 44

绑定进程


调试

绑定进程后,能够在指令窗口输入g字母命令,然后回车。恐怕用快速键F5。就能够在调整中运行进度了。注意:要求pdb文件,和exe或dll放在一齐,可能上文提到的把pdb文件放在C:\MyCodesSymbols目录。因为调试音讯都以依赖pdb的文本时间戳举办定点历史文件的,所以在公告版本后,最棒备份一下代码和文件。不然版本发出去了,原生源码举行编写翻译了,pdb不雷同了,源码被涂改了,那么抓取到的*.dmp内部存款和储蓄器印象就无法准确地调试。

次第被windbg绑定后,F5运作,今后能够健康操作软件了。那时候软件有相当,命令窗口会打字与印刷相关的可怜命令,如下图:

Access violation–code c0000005 (first chance)

美高梅开户网址 45

调试

那种是金榜题名的内部存款和储蓄器禁止访问1二分。输入小写字母k命令,就可以打字与印刷旅馆。左窗口也是应和的源码,像vs那样调试。工具栏上有诸多调解窗口可以展现出来:

美高梅开户网址 46

调弄整理工具栏

如有的变量数据展现窗口:Locals

美高梅开户网址 47

变量体现窗口


命令

除去大旨的可视化调节和测试之外,windbg支持命令进行其余的水源调节和测试,能够依附实际必要开始展览利用,上边简要介绍常用的授命:

壹、查看版本音讯:version、vertarget。

2、查看模块新闻:lm、!dlls、!lmvi等。

③、调用栈:用k命令突显调用栈,用.frames命令切换栈帧。

肆、内部存款和储蓄器操作:读内部存款和储蓄器用d命令,写内存用e命令。

5、自动分析:!analyze、!owner等。

6、符号命令:.reload加载符号, .sympath设置符号路线, !sym设置符号选项。

7、进度线程:!process展现进程新闻;.process彰显当前经过,或用.process
/i切换当前历程;!peb彰显进程情状块内容;~命令展现线程列表,用~n
s可切换当前线程,n表示线程号;.thread展现当前线程。


分析dmp文件

Windbg是调治的利器,能够绑定进度张开调弄整理,也能够调理进程的内部存款和储蓄器影象*.dmp文件,一般是进程崩溃后系统一发布出的dmp文件,只怕程序try
catch用代码生成的dmp文件。分析dmp文件,也大致上以上步骤,只然而上面是绑定文件,这些是开辟dmp文件而已。

美高梅开户网址 48

打开 dump 文件


扩展

绑定进度,调节和测试dmp文件,当然除了windbg之外,还足以一贯用vs编写翻译器,这是最最但是的事,只是vs编译器容积实在太大了,没有windbg小巧方便。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图