代码遭逢的标题计算,Windbg使用表达

近年来在开荒服务后台的时候,使用c#调用了四个c++编写的dll,时期蒙受了一多种的题目,经过1番不遗余力最终都相继化解了,在此做个小结,方便以往参考,究竟那几个标题也都以很遍布的,主要有以下难点:

新近在支付服务后台的时候,使用c#调用了多个c++编写的dll,时期境遇了一七种的难点,经过一番着力最后都逐项化解了,在此做个总计,方便今后参考,毕竟这一个难点也都以很广阔的,主要有以下难题:

C#调用Java

将jar转换为dll
实际步骤 :下载3个 IKVM 配置好碰着变量 具体操作如下
一、将已经编译后的java中Class文件实行打包;打包命令JA奥迪Q5

  1. 此地
    java的装有类必须放在2个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

3、设置路线

解压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包文件。(写的时候尽量增加文件的门径名称,便于搜索生成后的dll文件

当今dll文件已经打响了,不过前面还有使用那个dll在丰裕到C#品种中运维的时候只怕会报错。这一个不当正是缺失一些IKVMxxxx.dll文件,那么些文件都在ikvm-0.四陆.0.一\bin
文件下能够找到。

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

一、新建1个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#代码遭逢的标题计算,Windbg使用表达。项目中

六、测试

在C#种类中使用java类,其方法同java。首先用using 包名,那样才干找到类

术语、缩略语

  • 项目对照难题
  • 内部存款和储蓄器释放难点
  • 本子难题(x8六与x6四)
  • 编写翻译难题(静态与动态)
  • 财富加载难点
  • 十二分捕获与主题材料一定
  • vs实时调节和测试问题
  • 亚洲必赢官网,类别对照难题
  • 内部存储器释放难题
  • 本子难点(x捌陆与x64)
  • 编写翻译难题(静态与动态)
  • 财富加载难题
  • 不行捕获与主题材料一定
  • 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
    二〇一四/20一7(作者台式机和商家计算机安装差异版本,我都有得以落成过)
    MyEclipse201四

  • SDK:jdk-x八六、jdk-x6四(dll分为x86和x6四平台,和jdk的本子要相应,同1台计算机装七个版本的jdk比较烦,我利用的是系统布局jdk三10个人调节和测试三十七个人dll,然后myeclipse自带6十九个人jdk调节和测试陆九人dll)

三、筹算干活:

一、首先妄想上述运维平台,建议选用和体系位数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

记得保存。

下一场新建要求被调用的CSharp类代码。那里大家新建一些轻松的措施,为了演示效果我们独家对int、string、bool实行操作。如图:

亚洲必赢官网 4

下一场右键项目,点击生成。

亚洲必赢官网 5

第三步,完毕,干得呱呱叫。

2. 生成c++中间件

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

亚洲必赢官网 6

亚洲必赢官网 7

亚洲必赢官网 8

种类新建成功,右键项目,选拔属性。

亚洲必赢官网 9

亚洲必赢官网 10

image

(二)书写c++代码

添加cpp文件

亚洲必赢官网 11

亚洲必赢官网 12

编辑cpp文件

好了,c++和c#1切职业完结,右键生成。

亚洲必赢官网 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是三十二人那么c++dll一定也是三十一个人的,6四人也同样;

三.
windows陆十一个人下编写翻译的三11位dll测试失败,一时半刻不知晓是否陆十五位系统的来由,由于本身Computer虚拟机未有装上,就一贯不去3十几个人系统上测试了。

windbg 

项目对照难点

c#调用c++方法时,首先要在类中定义贰个与c++方法对应的外部方法,因为该方法是用C#言语定义的,那么肯定要清淤楚C#品类与c++类型怎么样对应,不然会导致调用失利,关于这么些主题素材其实不算什么难题,互连网有为数不少品种对照的篇章,都有很详细的附和列表,用的时候参考一下就足以了。还是能够使用工具,自动依据c++方法具名生成对应的C#
import方法具名,参考P/Invoke Interop
Assistant。不过有一个标题依旧要专注的,在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++方法时,首先要在类中定义1个与c++方法对应的外表方法,因为该办法是用C#语言定义的,那么一定要澄清楚C#类型与c++类型怎么着对应,不然会招致调用退步,关于这么些标题实际上不算什么难题,英特网有过多类型对照的稿子,都有很详细的呼应列表,用的时候参考一下就能够了。还足以行使工具,自动依照c++方法签字生成对应的C#
import方法签字,参考P/Invoke Interop
Assistant。然而有叁个难点要么要注意的,在x八陆格局下c#中的int对应c++中的int,而在x64模式下C#中的int是对应c++中的long,就那样2个细微的变量类型,在不经意间只怕就会招致c++代码出错。

再有一个主题材料是:托管的 PInvoke 签名与非托管的目标签名不匹配,可以在C#代码的措施本性上加上CallingConvention.Cdecl。如下所示:

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

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

内部存储器释放难题

出于那一个标题时常遇到,并且只要不可能化解的话鲜明不会再思索使用该dll了,那是四个可用性的主题材料。所以小编在调用c++方法的时候,平时都会先批量跑一边,通过日记记录下每调用三次艺术后,当前进程所据有的内部存款和储蓄器大小,那样在运营壹段时间今后,就能很明白的观望内存是还是不是持续提升,若是是的话就要求和编辑该dll的同事进行联络,给她们提供测试数据,确认产生难点的由来。有时就算C++中的方法开始展览了内部存款和储蓄器释放,并且在c++测试代码中壹度未有内部存款和储蓄器拉长难题了,不过在C#中调用的时候内部存款和储蓄器仍旧会频频提升,该难题也许跟使用的风貌有关,作者这边是因为调用了1个回到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++的测试工程再跑三次,看看是不是仍有该难点,假诺是验证真是c++的bug了,能够通报同事去修改bug了。

内部存储器难点偶尔并不会反映的老大明显,那须求我们更为缜密的观看比赛日志并发掘形成难点的实在原因。小编事先遭遇该地点的三个标题,刚开端内部存款和储蓄器升幅十二分醒目,经过三番五次与支出该dll的同事关系后,难题早已减轻的基本上了,可是多量测试后发掘内部存储器照旧会有好几高升,固然小幅十分小,但第六感告诉本身此中必有神奇,那假设上线跑个几天岂不是还得爆,后来自家把每二次调用c++方法后当前经过占用的内部存储器输出到文件中,经过全面察看,开采绝超过3/6文书(文件内容要传播c++方法中打开管理)都没难题,内部存款和储蓄器都很牢固,可是有非常的小部分文件在流传c++方法后,会导致内部存款和储蓄器相比较其他文件有3个威名昭著的增进,看来难点是出新在这一个文件中,随后把那些文件单独放在壹块儿开始展览巡回调用,内部存款和储蓄器一下子就大幅度增加了,前边就绝不说了,难题自然化解了。因而,要保持记日志的良好习惯,哪怕是在测试工程中

内存释放难点

出于这么些标题时常碰着,并且只要不可能化解的话分明不会再思量采纳该dll了,那是贰个可用性的难点。所以作者在调用c++方法的时候,平时都会先批量跑一边,通过日记记录下每调用三遍艺术后,当前进度所攻克的内部存款和储蓄器大小,那样在运作壹段时间以往,就能很驾驭的看来内部存款和储蓄器是或不是持续增高,假设是的话就要求和编辑该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了。

内存难题偶尔并不会展示的百般显眼,那亟需大家尤其细心的体察日志并发掘导致难题的的确原因。笔者前边遭受该地点的三个标题,刚开始内存上涨的幅度11分掌握,经过反复与开垦该dll的同事联系后,难点1度缓和的大半了,可是大量测试后意识内部存款和储蓄器依然会有一些高涨,尽管幅度非常小,但第六感告诉本身当中必有蹊跷,那尽管上线跑个几天岂不是还得爆,后来自身把每一遍调用c++方法后当前进程占用的内部存款和储蓄器输出到文件中,经过缜密调查,开采绝大多数文本(文件内容要传播c++方法中实行拍卖)都没难题,内存都很平静,不过有非常的小一些文本在传诵c++方法后,会促成内部存款和储蓄器相比较其余文件有二个明了的增长,看来难题是出新在那个文件中,随后把这么些文件单独放在一块儿举行巡回调用,内部存款和储蓄器一下子就大幅度升高了,后边就不用说了,难题理所当然解决了。因而,要保持记日志的良好习惯,哪怕是在测试工程中

dmp

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

本子不相称的话,在调试时会提示正在加载格式不正确的dll,固然使用的是3壹个人的c++版dll,要求把C#品种的编写翻译平台安装为x八陆,假使运用的是陆11个人的c++版dll,则设置为any
cpu和x6四都可以,这一个供给和谐依照实况对应好就足以了。要是程序对内部存款和储蓄器的利用比较高,最佳将次第编写翻译为6三人,因为30位程序对单进程的内部存款和储蓄器大小有限量,经测试最大不超越二G。因为作者的主次刚初阶选择的是叁拾位的c++版dll,并且在运维时索要调用这么些dll加载多数财富,加载完那一个能源进度占用的内部存款和储蓄器就大致快二G了,所以总会无缘无故的崩掉,以致在加载的进度中就径直崩掉了,当时预知到是3肆人的难题,后来让同事将dll重新编写翻译为六十二位后就未有那一个主题材料了。可以经过dumpbin命令判定一个dll是3三个人依旧陆十一人,展开vs开荒人士命令提醒,输入:dumpbin /headers 你的dll路径,例如:dumpbin /headers d:\test.dll,如下图所示:

亚洲必赢官网 18

1旦是311位dll,红框那里会彰显
亚洲必赢官网 19

此处有1个地点需求留意,默许asp.net项目在调节和测试时会运营在33个人下的iisexpress进度中,要是你的类型是陆十四位的,那么须要在VS大校iisexpress配置为63人格局,如下图所示:

亚洲必赢官网 20

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

本子不一样盟的话,在调节和测试时会提醒正在加载格式不正确的dll,假若采用的是310位的c++版dll,供给把C#项指标编写翻译平台安装为x八陆,即使运用的是陆拾贰个人的c++版dll,则设置为any
cpu和x6四都足以,那个须要协和根据真实境况对应好就足以了。假诺程序对内部存储器的接纳相比高,最棒将先后编写翻译为62个人,因为三拾壹人程序对单进度的内部存款和储蓄器大小有限制,经测试最大不抢先二G。因为本身的主次刚起头接纳的是33位的c++版dll,并且在运营时索要调用那几个dll加载大多能源,加载完那一个能源进程占用的内部存款和储蓄器就大约快二G了,所以总会无缘无故的崩掉,以致在加载的长河中就径直崩掉了,当时预见到是3几个人的难题,后来让同事将dll重新编写翻译为6十一个人后就未有那几个主题素材了。能够因而dumpbin命令推断2个dll是33个人依旧63人,展开vs开采人士命令提醒,输入:dumpbin /headers 你的dll路径,例如:dumpbin /headers d:\test.dll,如下图所示:

亚洲必赢官网 21

借使是三10位dll,红框这里会议及展览示
亚洲必赢官网 22

此间有3个地点供给专注,暗中同意asp.net项目在调节和测试时会运转在33位下的iisexpress进度中,假若您的门类是64人的,那么须要在VS准将iisexpress配置为陆十四位格局,如下图所示:

亚洲必赢官网 23

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

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

以此难点在运行时有时候会提醒dll加载不成事,这一个主题素材在不一致的计算机上会有两样的体现,有的存在这些难题,有的就运营通常。而本人本机就属叶昭君常的,陈设的服务器属于出难点的。出现那么些难题后,在肯定代码不易后,小编用depends.exe其1工具查看了须臾间导致难题的那些c++版的dll都重视什么程序集,在出标题标机器上会提示有部分注重的dll不设有,而这几个dll在运营如常的机器上是存在的。下图紫水晶色框中的为某个机器上也许会缺乏的dll:

亚洲必赢官网 24

若是贫乏相关dll,该条约的左侧会来得出3个风骚的问号。那么些标题得以采纳静态编写翻译实行化解,关于怎么样是静态编写翻译能够自行百度,总来说之正是将次第所依赖的dll编写翻译到程序集中,那样就算其余机器不存在那些dll也足以健康运作了,静态编写翻译能够在vs的类型性质中举办安装

亚洲必赢官网 25

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

刚刚的配备只可以消除不够MSVCP120.DLL和MSVC奥迪Q3120.DLL这一类难题,对于缺少MFC相关的dll,还要通过上面包车型地铁安排:

亚洲必赢官网 26

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

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

这些标题在运作时有时候会唤起dll加载不成事,这么些难题在分化的Computer上会有分歧的反映,有的存在这几个标题,有的就运转平常化。而作者本机就属周振天常的,安插的服务器属于出难题的。现身那些题目后,在确认代码不易后,作者用depends.exe其一工具查看了须臾间导致难题的可怜c++版的dll都依赖什么程序集,在出标题标机器上会提示有一些注重的dll不设有,而那几个dll在运维如常的机器上是存在的。下图浅绿灰框中的为有些机器上可能会缺点和失误的dll:

亚洲必赢官网 27

1经缺少相关dll,该条约标左侧会来得出二个风骚的问号。那些标题得以采取静态编写翻译进行化解,关于怎样是静态编写翻译能够自动百度,不问可见正是将顺序所依据的dll编写翻译到程序聚集,那样固然其它机器不设有这个dll也能够平常运行了,静态编写翻译能够在vs的门类性质中开始展览安装

亚洲必赢官网 28

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

刚刚的计划只好消除不够MSVCP120.DLL和MSVCKuga120.DLL这一类标题,对于缺少MFC相关的dll,还要通过上边包车型大巴布署:

亚洲必赢官网 29

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

Pdb

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

本条标题绝相比较隐蔽,出现时不会抛出非凡,只好通过c++方法重返的情形码来判定格局执行是还是不是成功,要不是在那边放了1个断点,特意看了一下,恐怕就遗漏那些主题材料了。

地方是那般的:
本身在webservice中调用c++版dll中的二个初阶化方法,该方法会加载一些财富文件,作者在vs中调护治疗实施的时候没难题,发表之后居然不能够加载能源,貌似是路线难点,作者把能源文件放到w三wp.exe的根目录下倒是能够成功加载,放在别的目录中就可怜,蒙受那些标题首先想到的或许是财富四处的目录权限不够导致iis不也许平常加载,因为事先有个同样的主题素材正是这样,但这一次将能源随地的目录改造为伊芙ryone用户的一点1滴调控权限如故11分,并且该难题只现出在b/s项目中,c/s项目尚未那个题目。并且该目录中存放了过多财富文件,有繁多少个c++版的dll都急需从此间加载,别的几个都没难点,就那1个dll不行,看来不是权力的难点。那时候又想是否相对路线的难题,那小编改成相对路线吧,结果难点依旧,后来在手艺群里有个大牌说试试Directory.SetCurrentDirectory,赶紧修改代码,测试了须臾间实在好使了。代码如下:

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

如注释所示,使用SetCurrentDirectory切换了当前专门的学业目录后,方法中所用的路子要改为相对路线,1初阶笔者用的是绝对路线,居然依然不可能加载。

后来发觉了该难点的来由,在动用的dll中又调用其余一个dll举行能源加载,只怕这么会形成那一个直接调用的dll现身路线难点,所以出现财富加载退步。

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

本条标题相对比较隐蔽,出现时不会抛出十分,只可以通过c++方法重返的图景码来判别格局实行是不是成功,要不是在此地放了3个断点,特意看了一下,只怕就遗漏这一个主题素材了。

此情此景是那样的:
本人在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中又调用此外2个dll进行财富加载,只怕这么会变成那多少个直接调用的dll出现路线难题,所以出现能源加载战败。

次第数据库文件。

老大捕获与主题材料一定

至于那多少个捕获,固然在方式中增添了特征HandleProcessCorruptedStateExceptionsSecurityCritical但要么捕获不到c++中的非凡,原因想必是c++在碰着一些相当时会产生程序间接退出,那样在C#中就自然捕获不到了,所以依然尽量有限支撑c++代码的健壮性。
如果在c#中调用了八个c++版dll中的方法,因为偶然捕获不到十三分,很难通过正规办法找到难题的原委,c++方法中就算出现十分大概会直接导致进度退出了,那时能够依据操作系统中的事件查看器来搜索非凡是出自哪个dll,同时在原有代码中注释掉那段调用该c++方法的代码,或许mock3个办法调用,保险该段代码无足够,然后再进行测试,要是无差距常,那么一旦解决了异常c++方法的主题材料就能够,假设还有万分那么就是此外dll的标题,然后能够编写制定测试代码单独测试曾经出难题的dll中的方法。异常捕获+事件查看器+日志能够帮忙开采者发掘先后的大多数主题素材与原因。

可怜捕获与难点一定

至于丰硕捕获,尽管在措施中增加了特点HandleProcessCorruptedStateExceptionsSecurityCritical但依旧捕获不到c++中的万分,原因恐怕是c++在遇见一些非常时会形成程序间接退出,那样在C#中就自然捕获不到了,所以还是尽量保障c++代码的健壮性。
如果在c#中调用了多个c++版dll中的方法,因为有时捕获不到1二分,很难通过不奇怪方式找到标题的原故,c++方法中壹经出现至极或然会平昔促成进度退出了,那时能够借助操作系统中的事件查看器来搜索11分是发源哪个dll,同时在原来代码中注释掉那段调用该c++方法的代码,恐怕mock几个主意调用,保障该段代码无不胜,然后再拓展测试,如若无丰富,那么一旦解决了丰裕c++方法的标题就能够,假诺还有尤其那么正是别的dll的主题素材,然后能够编写测试代码单独测试曾经出难题的dll中的方法。异常捕获+事件查看器+日志可以扶持开拓者开掘先后的诸多难题与原因。

Symbol

其他标题

任何主题材料

标志文件(Symbol
Files)是2个数额音讯文件,它富含了应用程序贰进制文件(比方:EXE、DLL等)调节和测试消息

1、0X1A截断全文的难点

那几个是c++代码读取文件时或许会遇上的七个难点,纵然在调治有个别难题的进度中开掘了那一个情景,但后来经开采dll的同事说难题的原由不是其一,那里就仅此记录一下吗,ifstream in("test.txt",'b');如此丰富第三个参数就不会截断了。

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

以此是c++代码读取文件时可能会遇到的2个难点,固然在调节和测试有些难题的进度中发觉了这几个景况,但后来经开荒dll的同事说问题的来头不是以此,那里就仅此记录一下啊,ifstream in("test.txt",'b');如此那般丰裕第三个参数就不会截断了。


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

四回蒙受那些难点都以在收工后出现的,当时也不清楚怎么着来头,后来经过windbg看了一晃测试程序和w3wp进度的转储文件,通过!gle -all一声令下发掘各类线程都在等候境况,如下图所示:

亚洲必赢官网 30

iis进度也是那样,本以为是代码死锁了,可是通过!locks命令也没觉察有任何非凡(关于那一个题目,能够参考
动用死锁分析,当时有个别懵,不领悟是哪些导致了那种气象,后来发出一件事情让自个儿弄驾驭了怎么,那是在快下班的时候,程序正好出现了3个老大(虽是卓殊,其实不会招致程序崩溃退出),那时服务器上弹出了3个vs实时调节和测试的提示窗口,笔者留意到iis的cpu使用率突然就降为0,测试程序的调节台也出口了线程等待的信息,联想到此前那些STATUS_WAIT_0的错误音讯以及貌似死锁的状态,作者备感觉恐怕是iis终止了具有线程,在等待vs实时调节和测试这些互动窗口的结束,由于平时都是在收工后才会张开测试程序来证实程序的安定团结,所以当弹出那些互动窗口时,一向不会有人去管理,线程不会直接这么等下去,最终测试程序就淡出了,iis也不知道该如何是好再持续处理请求了,那么些互动窗口也一般消失了(为啥用一般,因为作者尚未专门去留意,只是凭影象感觉在此之前没见过),想到那本人点了一下“撤消调节和测试”,程序继续往下运维了,也不再阻塞了。所以在程序运营的时候,最佳关闭VS的实时调节和测试功用,以防导致不要求的难题。进入visual
studio中,选拔【工具】->【选项】,点击【调式】,在【实时】选项卡中把【本机】【脚本】【托管】多少个对勾打消掉就能够了。

亚洲必赢官网 31

骨子里即是实时调节和测试窗口不见了,大家也得以通过系统事件来找到一些一望可知,如下图所示,只然则很难仅凭这几个事件就剖断难点的原委,因为服务器上运转了多个w三wp实例,只好说通过这几个状态抓好部分经验了。

亚洲必赢官网 32

实际上还有部分难题,到最近有点记不清了,就不敢贸然凭残存的那一点回想来叙述了,以便产生不须求的误解。对于境遇的难题,某个很显眼,某个很隐蔽,有些需求细致分析,有些要求在大方测试的景观下才会意识,那里只想说一句:测试很珍视,专门的学业需用心。

贰、vs实时调节和测试变成iis进度一向守候的问题

三次境遇这几个标题都以在下班后出现的,当时也不知底怎样来头,后来因而windbg看了瞬间测试程序和w三wp进程的转储文件,通过!gle -all命令开掘各类线程都在等候状态,如下图所示:

亚洲必赢官网 33

iis进度也是如此,本以为是代码死锁了,可是透过!locks一声令下也没发掘有其余越发(关于这一个主题材料,能够参考
利用死锁分析,当时不怎么懵,不知情是怎么样导致了这种境况,后来发生1件业务让自己弄明白了为啥,那是在快下班的时候,程序正好出现了三个要命(虽是卓殊,其实不会导致程序崩溃退出),那时服务器上弹出了三个vs实时调节和测试的唤醒窗口,小编注意到iis的cpu使用率突然就降为0,测试程序的调控台也出口了线程等待的新闻,联想到在此之前那个STATUS_WAIT_0的错误新闻以及貌似死锁的景况,作者觉获得大概是iis终止了具备线程,在等候vs实时调节和测试那个互动窗口的截至,由于日常都以在收工后才会张开测试程序来证实程序的稳定性,所以当弹出那么些互动窗口时,一向不会有人去管理,线程不会直接这么等下去,最终测试程序就淡出了,iis也无从再持续管理请求了,这一个互动窗口也一般消失了(为何用一般,因为本人未有专门去注意,只是凭影像感到从前没见过),想到这自个儿点了弹指间“打消调节和测试”,程序继续往下运作了,也不再阻塞了。所以在程序运营的时候,最佳关闭VS的实时调节和测试功效,防止产生不须要的标题。进入visual
studio中,采用【工具】->【选项】,点击【调式】,在【实时】选项卡中把【本机】【脚本】【托管】八个对勾撤除掉就足以了。

亚洲必赢官网 34

实则正是实时调节和测试窗口不见了,大家也足以透过系统事件来找到一些马迹蛛丝,如下图所示,只可是很难仅凭那些事件就判定难点的案由,因为服务器上运营了五个w三wp实例,只可以说通过那些意况增加部分经验了。

亚洲必赢官网 35

其实还有一对标题,到现行反革命不怎么记不清了,就不敢贸然凭残存的那一点回想来叙述了,以便产生不须要的误解。对于蒙受的题目,有个别很强烈,有些很隐蔽,某些需求细致分析,有些需求在大批量测试的情景下才会发现,这里只想说一句:测试很首要,职业需用心。

概述

Windbg是Windows平台下庞大的工具。绝相比较于Visual
Studio,它是三个轻量级的调整工具,所谓轻量级指的是它的安装文件大小异常的小,然而其调解效率,却比VS更为强劲。它的其余3个用途是能够用来分析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的标识文件,也正是系统暗许的1对pdb文件,那几个文件不是系统自带的,须求安顿好链接,第一次调节和测试的时候windbg暗中认可下载须要的缺点和失误的symbol文件。

亚洲必赢官网 37

pdb 下载的文件


Windbg工具配置

标识配置Symbol File Path

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

亚洲必赢官网 38

标识配置

源码路线配置Source File Path

工具不会智能定位到对应的源码,所以要布局你的源码工程的门路,是工程文件(举例这种格式的文书:*.vcxproj)所在的门道。

亚洲必赢官网 39

源码配置1

亚洲必赢官网 40

源码地点


编写翻译器配置

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

取缔优化项:

亚洲必赢官网 41

不准优化项一

亚洲必赢官网 42

明确命令禁止优化项二

浮动程序数据库文件

亚洲必赢官网 43

pdb 文件


使用

工具进行应用前布署后,能够拓展专业了。那里介绍绑定进度打开调解的操作步骤。


绑定进度

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

亚洲必赢官网 44

绑定进度


调试

绑定进度后,能够在指令窗口输入g字母命令,然后回车。也许用火速键F五。就可以在调节和测试中运作进度了。注意:供给pdb文件,和exe或dll放在一块儿,或然上文提到的把pdb文件放在C:\MyCodesSymbols目录。因为调节和测试音信都是基于pdb的文本时间戳实行固定历史文件的,所以在宣布版本后,最佳备份一下代码和文件。不然版本发出去了,原生源码进行编写翻译了,pdb差别等了,源码被改变了,那么抓取到的*.dmp内部存款和储蓄器影像就不能够确切地调节和测试。

次第被windbg绑定后,F5运作,今后得以健康操作软件了。那时候软件有10分,命令窗口会打字与印刷相关的丰裕命令,如下图:

Access violation–code c0000005 (first chance)

亚洲必赢官网 45

调试

那种是独立的内存禁止访问11分。输入小写字母k命令,就能够打字与印刷仓库。左窗口也是对应的源码,像vs那样调节和测试。工具栏上有诸多调节和测试窗口能够显得出来:

亚洲必赢官网 46

调和工具栏

如部分变量数据显示窗口:Locals

亚洲必赢官网 47

变量展现窗口


命令

除此而外大旨的可视化调节和测试之外,windbg援救命令进行其它的基石调节和测试,能够依赖实际须求展开应用,上面简要介绍常用的命令:

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

2、查看模块消息:lm、!dlls、!lmvi等。

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

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

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

6、符号命令:.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地图