威尼斯人线上娱乐

代码蒙受的主题素材总括,Windbg使用表明书

28 4月 , 2019  

威尼斯人线上娱乐,近来在付出服务后台的时候,使用c#调用了四个c++编写的dll,时期境遇了壹层层的难题,经过1番不遗余力最终都逐项化解了,在此做个小结,方便未来参考,究竟这几个难点也都以很广阔的,首要有以下难点:

近来在付出服务后台的时候,使用c#调用了八个c++编写的dll,时期蒙受了1雨后冬笋的标题,经过1番开足马力最终都壹1化解了,在此做个小结,方便未来参考,毕竟那些主题材料也都以很分布的,主要有以下难点:

C#调用Java

将jar转换为dll
切切实实步骤 :下载多个 IKVM 配置好碰着变量 具体操作如下
壹、将曾经编写翻译后的java中Class文件进行李包裹装;打包命令JABMWX五

  1. 此间
    java的全体类必须放在一个Package中,不要使用缺省的包,C#会找不到类之间的调用(C#貎似不能够引用此外dll里的默许namespace里边的剧情,所以java文件必须申明包,以便被调换到命名空间。其它,因为
    java中暗中认可访问权限的诀要会被转变来internal方法,所以在java中必须将那一个艺术显式地宣称为public),要求自身建,笔者用的是eclipse,写完程序直接导出成jar文件。

除此以外今后这几个版本好像不扶助Java
图形分界面,反正笔者调节和测试时,一旦new1个控件,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的主目录。

4、将java的jar包调换为.dll控件

选拔的吩咐:ikvmc -out:IKVM.dll test.jar (整个操作这一个是不可缺少的。)

里头IKVM.dll为就要变化的.dll控件文件名;test.jar(尽量增多上文件的门径)为事前打包好的jar包文件。(写的时候尽量增添文件的路径名称,便于寻觅生成后的dll文件

今昔dll文件已经成功了,不过后边还有使用这几个dll在丰盛到C#品种中运作的时候大概会报错。那一个不当就是缺少一些IKVMxxxx.dll文件,那个文件都在ikvm-0.四陆.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

二、增加已改变的.dll文件

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

六、测试

在C#品种中动用java类,其情势同java。首先用using 包名,那样本事找到类

术语、缩略语

  • 项目对照难题
  • 内部存款和储蓄器释放难点
  • 本子难点(x八六与x64)
  • 编写翻译问题(静态与动态)
  • 能源加载难点
  • 老大捕获与难点一定
  • vs实时调节和测试难题
  • 体系对照难点
  • 内部存款和储蓄器释放难点
  • 本子难题(x8陆与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
    二〇一四/2017(作者台式机和商家Computer安装不相同版本,小编都有得以实现过)
    MyEclipse201肆

  • SDK:jdk-x八陆、jdk-x64(dll分为x8陆和x6肆平台,和jdk的本子要对应,同一台计算机装四个版本的jdk相比烦,作者动用的是系统安插jdk三16人调节和测试3十一人dll,然后myeclipse自带陆拾二个人jdk调试6多少人dll)

三、打算职业:

代码蒙受的主题素材总括,Windbg使用表明书。壹、首先策画上述运转平台,建议选拔和类别位数1致的jdk(安装vs、myeclipse或eclipse或sts);

2、下载jna.jar
:JNA下载
(下载jna-4.4.0.jar 和 jna-platform-4.4.0),也可以
本地下载

四、开始CODE

1. 生成c#DLL

(一)以处理人格局运行vs(项目涉嫌到注册com组件,必须以管理人运维本领到位),新建c#项目

威尼斯人线上娱乐 1

(二)设置c#项目

率先,右键刚刚新建的Invoke项目,点击属性。

威尼斯人线上娱乐 2

承接设置项目性质。

威尼斯人线上娱乐 3

记得保存。

下一场新建要求被调用的C夏普类代码。那里大家新建一些简练的章程,为了演示效果我们独家对int、string、bool进行操作。如图:

威尼斯人线上娱乐 4

接下来右键项目,点击生成。

威尼斯人线上娱乐 5

率先步,实现,干得美好。

2. 生成c++中间件

(一)新建c++项目并安装属性

威尼斯人线上娱乐 6

威尼斯人线上娱乐 7

威尼斯人线上娱乐 8

类型新建成功,右键项目,选用属性。

威尼斯人线上娱乐 9

威尼斯人线上娱乐 10

image

(二)书写c++代码

添加cpp文件

威尼斯人线上娱乐 11

威尼斯人线上娱乐 12

编辑cpp文件

好了,c++和c#整套干活完结,右键生成。

威尼斯人线上娱乐 13

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

五、编写java代码

壹. 新建java project
,注意采取和dll平台壹致的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都能够高枕无忧传递了,事实上其余品种的也得以兑现,只要坚守不一样语言之间的系列对应关系就足以了,具体的连串涉及得以百度。

6、注意事项

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是312位那么c++dll一定也是311个人的,陆16人也同等;

三.
windows63人下编写翻译的三拾1人dll测试退步,目前不亮堂是或不是62位系统的原故,由于自家Computer虚拟机未有装上,就从不去三十几人系统上测试了。

windbg 

花色对照难点

c#调用c++方法时,首先要在类中定义三个与c++方法对应的外表方法,因为该格局是用C#言语定义的,那么自然要搞清楚C#体系与c++类型怎么样对应,不然会促成调用退步,关于那些标题实际上不算什么难题,网络有众多门类对照的文章,都有很详细的应和列表,用的时候参考一下就可以了。还足以选择工具,自动依照c++方法具名生成对应的C#
import方法签字,参考P/Invoke Interop
Assistant。但是有1个标题如故要留心的,在x8陆格局下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)]

品种对照难题

c#调用c++方法时,首先要在类中定义贰个与c++方法对应的外部方法,因为该情势是用C#语言定义的,那么必然要搞清楚C#品种与c++类型怎么着对应,否则会变成调用失败,关于那个主题素材其实不算什么难题,网络有数不清项目对照的篇章,都有很详细的关照列表,用的时候参考一下就足以了。仍可以使用工具,自动根据c++方法签字生成对应的C#
import方法具名,参考P/Invoke Interop
Assistant。可是有一个主题材料也许要注意的,在x八陆形式下c#中的int对应c++中的int,而在x64模式下C#中的int是对应c++中的long,就像此二个相当小的变量类型,在不经意间或许就会促成c++代码出错。

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

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

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

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

出于这些标题时常境遇,并且只要无法化解的话料定不会再思考采取该dll了,那是二个可用性的难题。所以本身在调用c++方法的时候,平日都会先批量跑一边,通过日记记录下每调用三回艺术后,当前历程所攻下的内部存款和储蓄器大小,那样在运转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的同事联系后,难题一度缓和的几近了,不过多量测试后发觉内部存款和储蓄器依然会有一些高涨,就算大幅十分小,但第陆感告诉自个儿个中必有好奇,那如若上线跑个几天岂不是还得爆,后来本身把每回调用c++方法后当前进度占用的内部存款和储蓄器输出到文件中,经过仔细察看,开采绝大多数文书(文件内容要传播c++方法中展开始拍片卖)都没难点,内部存款和储蓄器都很牢固,然则有相当的小片段文书在传唱c++方法后,会变成内部存款和储蓄器相比其它文件有三个醒目标增加,看来难点是出新在那几个文件中,随后把这么些文件单独放在1块儿实行巡回调用,内部存款和储蓄器一下子就大幅度提升了,前面就毫无说了,难题理所当然消除了。因此,要保持记日志的良好习惯,哪怕是在测试工程中

内存释放难点

是因为这些标题平时遇上,并且只要不能一蹴而就的话肯定不会再思索选择该dll了,这是一个可用性的标题。所以小编在调用c++方法的时候,平日都会先批量跑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了。

内部存款和储蓄器难点偶尔并不会呈现的尤其眼看,那亟需大家更为缜密的观望日志并开掘导致难点的着实原因。小编在此以前遇到该地点的多个难题,刚伊始内存上涨的幅度13分显眼,经过一再与支出该dll的同事联系后,难点早已缓慢解决的几近了,不过多量测试后发觉内存依旧会有几许高升,即使小幅度极小,但第5感告诉自个儿当中必有好奇,那假设上线跑个几天岂不是还得爆,后来本身把每一遍调用c++方法后当前历程占用的内部存款和储蓄器输出到文件中,经过仔细观察,发现绝大多数文书(文件内容要传播c++方法中张开始拍录卖)都没难题,内部存款和储蓄器都很稳固,不过有非常的小部分文件在传唱c++方法后,会导致内部存款和储蓄器比较其余文件有3个显眼的坚实,看来难点是出现在那些文件中,随后把这么些文件单独放在一同张开巡回调用,内部存储器一下子就小幅巩固了,前面就不要说了,难题自然化解了。由此,要保持记日志的良好习惯,哪怕是在测试工程中

dmp

本子难点(x八陆与x64)

本子不相配的话,在调节和测试时会提醒正在加载格式不正确的dll,如若选取的是三12人的c++版dll,须求把C#项目标编写翻译平台安装为x8六,如若运用的是陆10位的c++版dll,则设置为any
cpu和x64都能够,这么些需求和谐依照实情对应好就能够了。假若程序对内部存储器的选取相比高,最棒将次第编写翻译为陆拾人,因为三十个人程序对单进度的内部存款和储蓄器大小有限定,经测试最大不领先二G。因为自个儿的次序刚开端应用的是三十九个人的c++版dll,并且在运作时必要调用那一个dll加载许多能源,加载完这一个能源进度占用的内部存款和储蓄器就基本上快2G了,所以总会莫明其妙的崩掉,乃至在加载的进程中就直接崩掉了,当时预见到是三14人的标题,后来让同事将dll重新编写翻译为6三位后就从不那几个题材了。能够由此dumpbin命令判别多少个dll是3九位依旧61位,打开vs开荒职员命令提醒,输入:dumpbin /headers 你的dll路径,例如:dumpbin /headers d:\test.dll,如下图所示:

威尼斯人线上娱乐 18

借使是3二人dll,红框那里会显得
威尼斯人线上娱乐 19

此间有二个地方须求留意,私下认可asp.net项目在调治时会运营在三玖人下的iisexpress进度中,如若您的门类是6十二位的,那么要求在VS少校iisexpress配置为六十一人格局,如下图所示:

威尼斯人线上娱乐 20

本子难点(x捌陆与x6四)

本子不相称的话,在调节和测试时会提醒正在加载格式不正确的dll,如若利用的是32个人的c++版dll,必要把C#品类的编写翻译平台安装为x八陆,假诺利用的是61个人的c++版dll,则设置为any
cpu和x6肆都得以,那么些要求团结依据实际情形对应好就足以了。要是程序对内存的施用相比高,最佳将顺序编写翻译为陆九个人,因为311人程序对单进程的内部存款和储蓄器大小有限定,经测试最大不超越二G。因为自个儿的先后刚开首选择的是三拾1位的c++版dll,并且在运行时需求调用这个dll加载繁多财富,加载完这几个能源进程占用的内部存款和储蓄器就大概快二G了,所以总会莫明其妙的崩掉,以致在加载的长河中就径直崩掉了,当时预知到是三十2人的主题素材,后来让同事将dll重新编写翻译为63个人后就不曾那一个难题了。能够透过dumpbin命令判定二个dll是30个人依旧陆17个人,展开vs开垦人士命令提醒,输入:dumpbin /headers 你的dll路径,例如:dumpbin /headers d:\test.dll,如下图所示:

威尼斯人线上娱乐 21

假要是三10人dll,红框那里会来得
威尼斯人线上娱乐 22

此处有多个地点供给专注,暗中认可asp.net项目在调度时会运转在三十六个人下的iisexpress进度中,若是您的类型是63个人的,那么须求在VS团长iisexpress配置为63人格局,如下图所示:

威尼斯人线上娱乐 23

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

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

其1标题在运转时有时候会唤起dll加载不成功,这么些难点在不一致的Computer上会有差别的呈现,有的存在那个难题,有的就运转平常化。而自个儿本机就属周丽娟常的,布置的服务器属于出难点的。出现那几个难点后,在确定代码不易后,小编用depends.exe本条工具查看了壹晃导致问题的要命c++版的dll都依靠什么程序集,在出难题的机器上会提醒有部分借助的dll不设有,而这几个dll在运转平常化的机器上是存在的。下图蔚蓝框中的为有个别机器上也许会不够的dll:

威尼斯人线上娱乐 24

设若缺乏相关dll,该条款的右边会来得出三个艳情的问号。这些标题得以选拔静态编写翻译举行消除,关于如何是静态编写翻译能够自行百度,由此可见便是将次第所重视的dll编写翻译到程序聚焦,那样就算别的机器不设有这一个dll也足以健康运作了,静态编写翻译能够在vs的品种性质中开始展览设置

威尼斯人线上娱乐 25

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

刚刚的配备只可以消除不够MSVCP120.DLL和MSVC卡宴120.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奥迪Q7120.DLL那壹类主题素材,对于贫乏MFC相关的dll,还要通过上面包车型地铁布置:

威尼斯人线上娱乐 29

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

Pdb

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

以此主题素材相对比较隐蔽,出现时不会抛出万分,只可以通过c++方法重临的意况码来剖断情势推行是不是成功,要不是在此处放了八个断点,特意看了壹晃,可能就遗漏这些主题素材了。

场地是这么的:
自身在webservice中调用c++版dll中的三个开始化方法,该方法会加载一些财富文件,笔者在vs中调弄整理执行的时候没难点,发表之后居然无法加载能源,貌似是门路难题,小编把财富文件放到w3wp.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出现路线难点,所以出现财富加载失利。

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

那么些主题材料绝比较较隐蔽,出现时不会抛出尤其,只好通过c++方法重回的情状码来剖断形式推行是或不是成功,要不是在那里放了叁个断点,特意看了弹指间,恐怕就遗漏这几个主题材料了。

气象是如此的:
本人在webservice中调用c++版dll中的1个初步化方法,该方法会加载一些能源文件,笔者在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中又调用别的3个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中的方法,因为有时候捕获不到那多少个,很难通过正规方法找到难题的原由,c++方法中壹经出现极度也许会从来变成进度退出了,那时能够凭借操作系统中的事件查看器来寻觅分外是来自哪个dll,同时在原来代码中注释掉那段调用该c++方法的代码,只怕mock1个措施调用,保险该段代码一点差异也未有常,然后再实行测试,假若无尤其,那么只要解决了尤其c++方法的主题素材就可以,假如还有尤其那么便是此外dll的难题,然后能够编写制定测试代码单独测试曾经出题目的dll中的方法。异常捕获+事件查看器+日志可以协助开垦者开掘先后的大许多标题与原因。

Symbol

其余标题

其他主题素材

标记文件(Symbol
Files)是多个多少音讯文件,它含有了应用程序二进制文件(举例:EXE、DLL等)调节和测试音讯

1、0X1A截断全文的主题素材

那些是c++代码读取文件时恐怕会遭遇的2个难题,即便在调整有些难题的经过中发觉了这几个情景,但新兴经开垦dll的同事说难点的原故不是以此,那里就仅此记录一下吧,ifstream in("test.txt",'b');诸如此类丰盛第四个参数就不会截断了。

壹、0X一A截断全文的标题

那么些是c++代码读取文件时大概会境遇的三个主题素材,固然在调治有些难题的进度中窥见了那些场馆,但后来经开采dll的同事说难点的案由不是其壹,那里就仅此记录一下吧,ifstream in("test.txt",'b');那般丰裕第三个参数就不会截断了。


二、vs实时调节和测试变成iis进度一贯等候的标题

三回遭受那一个标题都以在下班后出现的,当时也不知底哪些来头,后来由此windbg看了弹指间测试程序和w三wp进度的转储文件,通过!gle -all指令开采各类线程都在等候状态,如下图所示:

威尼斯人线上娱乐 30

iis进程也是如此,本以为是代码死锁了,不过通过!locks一声令下也没觉察有别的分外(关于这么些标题,可以参考
应用死锁分析,当时有个别懵,不明了是怎么样导致了那种情况,后来发生一件事情让自家弄精晓了干吗,那是在快下班的时候,程序正好出现了多少个格外(虽是卓殊,其实不会导致程序崩溃退出),那时服务器上弹出了三个vs实时调节和测试的提拔窗口,作者留意到iis的cpu使用率突然就降为0,测试程序的调节台也出口了线程等待的音讯,联想到以前这一个STATUS_WAIT_0的错误音讯以及貌似死锁的场地,我深以为大概是iis终止了具有线程,在守候vs实时调试那个互动窗口的完成,由于平日都以在收工后才会展开测试程序来证实程序的稳定性,所以当弹出那一个互动窗口时,平素不会有人去管理,线程不会直接如此等下去,最终测试程序就淡出了,iis也无从再持续管理请求了,那几个互动窗口也诚如消失了(为何用一般,因为本身未有特意去留意,只是凭印象感到在此之前没见过),想到那小编点了弹指间“撤除调试”,程序继续往下运营了,也不再阻塞了。所以在程序运维的时候,最佳关闭VS的实时调节和测试作用,防止导致不必要的题目。进入visual
studio中,选拔【工具】->【选项】,点击【调式】,在【实时】选项卡中把【本机】【脚本】【托管】多少个对勾撤除掉就足以了。

威尼斯人线上娱乐 31

实际就是实时调节和测试窗口不见了,我们也足以通过系统事件来找到一些一望可知,如下图所示,只可是很难仅凭那几个事件就剖断难点的因由,因为服务器上运转了多少个w3wp实例,只可以说经过这几个情况做实部分经历了。

威尼斯人线上娱乐 32

其实还有壹部分难点,到今天多少记不清了,就不敢贸然凭残存的这点回想来讲述了,以便产生不须求的误解。对于遭受的主题材料,有个别很强烈,某些很隐蔽,某些必要密切分析,有些供给在大气测试的情事下才会发觉,那里只想说一句:测试很首要,专门的学问需用心。

二、vs实时调试形成iis进度一向守候的标题

四次遇上那么些标题都以在收工后出现的,当时也不知晓怎么来头,后来因此windbg看了弹指间测试程序和w三wp进度的转储文件,通过!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更为有力。它的其余多少个用处是能够用来分析dump数据,还足以调解进度死锁之类的。调试功效,类似于Visual
Studio,还协助命令格局。该文档只适用于VC++,而C#的还亟需相当开展部分配置,原理差不离一样。

Windbg只是三个工具,要驾驭在那之中央的应用方法,和调解命令,在推行中不断完善自个儿的调整花招。同时能够参考一下师父们的文献《Windows用户态程序便捷排错》,《Windows高档调节和测试》,《软件调试》


下载

Windbg使用尤其常见,网络非凡多的下载版本,而且文书档案也相比多,能够到CSDN可能其余网址下载,支持蓝色包运维。


配置

Windbg在应用前,需求开始展览铺排。

一.一情形变量

1、增多境遇变量:_NT_SYMBOL_PATH

2、境况变量值:

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

威尼斯人线上娱乐 36

情形变量配置

3、依据景况变量值,在C盘下新建文件夹:MyCodesSymbols,MyLocalSymbols那四个文件夹主要存放在windows的暗记文件,相当于系统私下认可的部分pdb文件,这个文件不是系统自带的,需求配置好链接,第叁回调节和测试的时候windbg暗中同意下载须求的缺点和失误的symbol文件。

威尼斯人线上娱乐 37

pdb 下载的公文


Windbg工具配置

标识配置Symbol File Path

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

威尼斯人线上娱乐 38

标识配置

源码路线配置Source File 帕特h

工具不会智能定位到相应的源码,所以要安顿你的源码工程的渠道,是工程文件(比方那种格式的文件:*.vcxproj)所在的不二秘籍。

威尼斯人线上娱乐 39

源码配置一

威尼斯人线上娱乐 40

源码地点


编写翻译器配置

扶助VC陆以上的Visual Studio编写翻译器,设置相关的性子

明确命令禁止优化项:

威尼斯人线上娱乐 41

取缔优化项一

威尼斯人线上娱乐 42

禁绝优化项2

扭转程序数据库文件

威尼斯人线上娱乐 43

pdb 文件


使用

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


绑定进度

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

威尼斯人线上娱乐 44

绑定进程


调试

绑定进程后,能够在命令窗口输入g字母命令,然后回车。恐怕用急忙键F伍。就能够在调度中运转进度了。注意:要求pdb文件,和exe或dll放在一块儿,只怕上文提到的把pdb文件放在C:\MyCodesSymbols目录。因为调节和测试信息都以依赖pdb的文书时间戳进行一定历史文件的,所以在公布版本后,最佳备份一下代码和文书。不然版本发出去了,原生源码进行编写翻译了,pdb不一致等了,源码被涂改了,那么抓取到的*.dmp内部存款和储蓄器影像就不能够可信地调节和测试。

先后被windbg绑定后,F5周转,今后能够平常操作软件了。那时候软件有格外,命令窗口会打字与印刷相关的尤其命令,如下图:

Access violation–code c0000005 (first chance)

威尼斯人线上娱乐 45

调试

那种是一流的内部存款和储蓄器禁止访问非凡。输入小写字母k命令,就可以打字与印刷酒店。左窗口也是应和的源码,像vs那样调节和测试。工具栏上有多数调度窗口能够显示出来:

威尼斯人线上娱乐 46

调理工科具栏

如部分变量数据展现窗口:Locals

威尼斯人线上娱乐 47

变量显示窗口


命令

除开大旨的可视化调节和测试之外,windbg扶助命令举办别的的基本调节和测试,能够凭仗实际须要举行应用,上面简介常用的一声令下:

1、查看版本音信:version、vertarget。

二、查看模块音信:lm、!dlls、!lmvi等。

3、调用栈:用k命令呈现调用栈,用.frames命令切换栈帧。

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

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

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

柒、进程线程:!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地图