C#调用C++编写的dll在IIS中报错,vs里面没有问题
来源:互联网 发布:怎么使用淘宝直通车 编辑:程序博客网 时间:2024/06/05 03:28
项目中,用C#开发了一个web服务后台,提供接口以供外部调用。最近功能更新,更改了某个接口的实现,发版并测试之后,发现在vs中调试一切正常,但是发布到IIS中运行,就会出现问题,该接口调用不了。由于是java web调用C#后台,调用后台的代码,是由web服务后台的wsdl文件生成,现在接口调用出错,加上只有此次更改后的接口调用出错,其它接口一切正常,而且在vs编译器下又一切正常。所以,第一直观肯定是这里的java调用出现问题。
第1步,确定是java调用问题。
尝试重新生成java调用web后台的代码。因为VS中一切正常,IIS中就不行,于是发布到IIS之后,利用运行起来的wsdl文件,生成新的调用代码,试了之后,还是不行。通过解析java war包后的文件夹内容,然后进行比较,发现其实war包的内容是一样的,也就是说生成java调用C# web后台的代码没有变化,问题不在这里。
第2步,确定是IIS配置问题。
这个解决方式百度上有很多,基本上就是修改IIS配置,同时对调用的dll,通过右键属性->安全,授予IIS用户权限。处理之后,依然没有解决问题。
第3步,确定是tomocat配置问题。
查看tomocat下的日志,发现有日志记录,意思是调用接口的类中,出现了javax.xml.ws.WebServiceException: java.net.SocketException: Connection reset错误,网上有建议将生成的wsdl文件里面的接口地址处理成要发布的IP地址,没有解决此问题。另外tomocat的配置本来就没有修改,之前就没有问题,所以紧接着确定是代码问题。
第4步,调用的dll,编译生成的代码有问题。
跟写dll的C++沟通,基本确定没问题,毕竟,如果有问题的话,那么在编译器调试时就会出现问题。
第5步,调用dll的C#代码有问题。
好不容易来到了第四步,问题真就出在这里!发现的方式是,在调用dll前面和后面直接返回接口调用,实际效果是一个可以一个不可以,由此锁定问题。在进行C#调用C++中,代码如下:
修改方式:返回值不用string,采用IntPtr。IntPtr用于表示指针或句柄的平台特定类型,C#中的IntPtr类型称为“平台特定的整数类型”,你也可以理解成变相的指针,这里由于我们需要的还是string类型的值,所以返回值不能直接使用,还需要转换。所以修改该函数返回值类型,并添加一个方法来间接调用:
第1步,确定是java调用问题。
尝试重新生成java调用web后台的代码。因为VS中一切正常,IIS中就不行,于是发布到IIS之后,利用运行起来的wsdl文件,生成新的调用代码,试了之后,还是不行。通过解析java war包后的文件夹内容,然后进行比较,发现其实war包的内容是一样的,也就是说生成java调用C# web后台的代码没有变化,问题不在这里。
第2步,确定是IIS配置问题。
这个解决方式百度上有很多,基本上就是修改IIS配置,同时对调用的dll,通过右键属性->安全,授予IIS用户权限。处理之后,依然没有解决问题。
第3步,确定是tomocat配置问题。
查看tomocat下的日志,发现有日志记录,意思是调用接口的类中,出现了javax.xml.ws.WebServiceException: java.net.SocketException: Connection reset错误,网上有建议将生成的wsdl文件里面的接口地址处理成要发布的IP地址,没有解决此问题。另外tomocat的配置本来就没有修改,之前就没有问题,所以紧接着确定是代码问题。
第4步,调用的dll,编译生成的代码有问题。
跟写dll的C++沟通,基本确定没问题,毕竟,如果有问题的话,那么在编译器调试时就会出现问题。
第5步,调用dll的C#代码有问题。
好不容易来到了第四步,问题真就出在这里!发现的方式是,在调用dll前面和后面直接返回接口调用,实际效果是一个可以一个不可以,由此锁定问题。在进行C#调用C++中,代码如下:
[DllImport("SDK.dll", CallingConvention = CallingConvention.Cdecl)]private static extern string TEST_SDK_GetVersion();上面是一个简单的调用代码,获取版本号,返回的是string类型。但实际在跟C++工程师沟通后,得知该函数在C++中,返回的是string类型的指针。这里涉及到内存管理的问题,因为VS和IIS应用程序池的内存管理方式存在差别,所以导致VS里面运行正常,发步IIS后出现问题。
修改方式:返回值不用string,采用IntPtr。IntPtr用于表示指针或句柄的平台特定类型,C#中的IntPtr类型称为“平台特定的整数类型”,你也可以理解成变相的指针,这里由于我们需要的还是string类型的值,所以返回值不能直接使用,还需要转换。所以修改该函数返回值类型,并添加一个方法来间接调用:
[DllImport("SDK.dll", CallingConvention = CallingConvention.Cdecl)]private static extern IntPtr TEST_SDK_GetVersion();private string Get_TEST_SDK_GetVersion(){ return Marshal.PtrToStringAnsi(TEST_SDK_GetVersion()); //转换为C#托管环境的string}
现在,改为调用Get_TEST_SDK_GetVersion方法即可。
总结:查看MSDN文档,Marshal.PtrToStringAnsi(IntPtr)方法为托管字符串的副本从非托管 ANSI 第一个空字符之前的所有字符 String, 并且每个将 ANSI 字符扩展为 Unicode,对于自定义封送处理或混合托管和非托管代码时很有用。通过该方法,将非托管C++的string指针的值,在托管代码C#中获取到。这样,也就理解了为啥在VS中调试或运行一切正常,而发布IIS上就有问题了。
阅读全文
0 0
- C#调用C++编写的dll在IIS中报错,vs里面没有问题
- 在C#中调用C++Builder编写的DLL
- 编写C#调用的C++DLL
- 编写C#调用的C++DLL
- 编写C#调用的C++DLL
- VS C#项目引用C++编写的DLL问题
- 关于在主程序里面调用DLL时,找不到DLL里面的路径问题
- C#中如何调用C++编写的DLL
- C#中如何调用C++编写的DLL
- C#中如何调用C++编写的DLL
- C#中如何调用C++编写的DLL
- C#调用C语言编写的dll示例
- C#调用非托管C编写DLL的数据类型转换
- 在C#中调用VC编写的dll库
- 在C#中调用VC编写的dll库
- 如何在MFC中调用C#编写的DLL
- 在C#中如何调用C++编写的DLL
- 在C#中调用VC编写的dll库
- MFC中CString类字符串与长整型、浮点型、字符数组char数据之间的相互转换
- poj3279 Fliptile 开关问题
- zdsoft screen recorder(屏幕录像工具)官方注册版V11.1.2下载 | screen recorder破解版含注册机
- NKOJ 3743 奶牛求幂 (启发式搜索)
- 【编译原理 01】
- C#调用C++编写的dll在IIS中报错,vs里面没有问题
- C++ strcpy与strncpy的注意事项
- Linux 创建新用户
- 1235: 会场安排问题(request maxnum )
- ride
- JAVA基础:SWING中JTextField限制只能输入数字
- python判断对象的类型(字典,列表,集合等)
- PAT Basic 1019
- Ijkplay视频播放简单快速集成