C#总结(四)调用C++动态库
由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序。在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题。最近一直在和C++ 打交道,C# 怎么调用C++ 类库函数。也遇到了一些问题,所以就来总结总结C#程序调用C++动态库时的各种坑。
1. 可能遇到的问题:
C#在调用动态库的过程中我也遇到了以下一些问题:
1、C++中有指针,C#中需要使用指针吗?
由于C++中的动态库中有指针参数,因此我也是用.NET的不安全代码,使用了C#的指针,但是也还是出现了一些问题,如在C#中传入的参数是一个二维数组时就出现了问题,最后只能改C++函数传入参数的参数类型。
2、C#和C++中的类型如何转换呢?
虽然C#和C++比较类似,但是其给我们的参数类型我们要与C#的参数类型一一对应起来,具体看后续说明。
3、C++函数中的CallingConventionCharSet 怎么设置?
调用C++函数之前一定要先确认,否则可能出现函数调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配的问题。函数的CallingConvention和CharSet,可以查看动态库对应的 .h头文件。
4、如何反编译C++的dll的名称,端口?
可以通过Dependency Walker工具进行反编译查看别人写的动态库的信息
5、指针函数如何传参?
对于函数需要的指针函数,C# 调用时,可以定义委托来传入参数。
6、需要注意C++ dll 编译的平台是x86还是x64,是多字节的还是双字节的(Unicode)。
2. 通过Dependency Walke查看dll的名称,端口
下载Dependency 后将对应的C++ dll文件加载进去,就尅看到动态库的对应的信息,同时也可以通过.h 头文件查看。
3. 如何调用
c#调用c++动态库一般我们这样写
[DllImport(SDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int IKSDK_Release();
1. DllImport的第一个参数SDK是动态库dll的路径,此dll放在程序运行的根目录或者c:windows/sytem32下,建议在程序根目录创建一个子目录来放置相应的C++ 动态库文件,方便以后更新。
2. CallingConvention 参数是c#调用c++的方式 是个枚举 msdn解释如下:
Cdecl | 调用方清理堆栈。这使您能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。 |
FastCal | 不支持此调用约定。 |
StdCall | 被调用方清理堆栈。这是使用平台 invoke 调用非托管函数的默认约定。 |
ThisCall | 第一个参数是 this 指针,它存储在寄存器 ECX 中。其他参数被推送到堆栈上。此调用约定用于对从非托管 DLL 导出的类调用方法。 |
Winapi | 此成员实际上不是调用约定,而是使用了默认平台调用约定。例如,在 Windows 上默认为 StdCall,在 Windows CE.NET 上默认为 Cdecl。 |
3. CharSet参数是控制名称重整以及将字符串参数封送到函数中的方式。 默认值为 CharSet.Ansi。
4. entrypoint参数用于标识函数在 DLL 中的位置。在托管对象中,目标函数的原名或序号入口点将标识跨越交互操作边界的函数。此外,您可以将入口点映射到一个不同的名称,这实际上是将函数重命名。一般默认不设置此参数。
5. 其他参数,请查看MSDN对于 DllImportAttribute 的说明。
4. 其他说明
C# 调用C++ 动态库,还有一个特别麻烦的问题就是参数对于的问题。后续会结合网上的资料总结一份详细的对照表。
C#总结(四)调用C++动态库的更多相关文章
- .netcore在linux下使用P/invoke方式调用linux动态库
http://www.mamicode.com/info-detail-2358309.html .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...
- c#调用c++动态库的一些理解
调用c++动态库一般我们这样写 [DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)] ...
- C#调用C++动态库(dll)
在实际软件开发过程中,由于公司使用了多种语言开发,在C#中可能需要实现某个功能,而该功能可能用其他语言已经实现了,那么我们可以调用其他语言写好的模块吗?还有就是,由于C#开发好的项目,我们可以利用re ...
- Java调用dll动态库
最近项目里使用java调用dll动态库,因此研究了一下这方面的东西. 使用的工具包如下 <dependency> <groupId>net.java.dev.jna</g ...
- 【C#】 使用Gsof.Native 动态调用 C动态库
[C#] 使用Gsof.Native 动态调用 C动态库 一.背景 使用C# 开发客户端时候,我们经常会调用一些标准的动态库或是C的类库.虽然C# 提供的PInvoke的方式,但因为使用的场景的多变, ...
- python调用.net动态库
# python调用.net动态库 ### pythonnet简介------------------------------ pythonnet是cpython的扩展- pythonnet提供了cp ...
- Delphi XE7调用C++动态库出现乱码问题回顾
事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...
- 使用ctypes在Python中调用C++动态库
使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #in ...
- C# 调用C++动态库注意事项
C# 调用C++动态库注意事项 最近项目上需要在C#中调用C++,期间遇到不少坑,总结如下: 1.in const char* 对应C#中string 或 IntPtr 2.out const ...
随机推荐
- JS通过decodeURIComponent函数解码
在我们调用后台接口的时候,如果后端传过来的字段是编码过的,那需要使用decodeURIComponent函数进行解码显示 var test1="http://www.jianshu.com/ ...
- MicroPython开发之物联网快速开发板
Python的火热让其运行在MCU端的MicroPython也逐渐迎来了春天.MicroPython的出现让Python这种"胶水语言"成功引用到嵌入式领域,也使得Python控制 ...
- 机器学习笔记3-Tensorflow简介
前言 前面两篇主要写了一些机器学习的基础概念,从本篇开始我们来了解下深度学习.深度学习是机器学习的一个子集,是一种特殊的数学模型.同样是从输入到输出,深度学习在这两者之间会有很多层称为"隐层 ...
- mysql如何执行关联查询与优化
mysql如何执行关联查询与优化 一.前言 在数据库中执行查询(select)在我们工作中是非常常见的,工作中离不开CRUD,在执行查询(select)时,多表关联也非常常见,我们用的也比较多,那么m ...
- jsp分页
<%! int pataSize=5;// 每页多少数据 int totalCount =0; //数据共多少 int pageCount = 0; ///数据共有多少页 ...
- 【转载】Linux cgroup资源隔离各个击破之 - io隔离
Linux Cgroup blkio子系统的用法. blkio子系统支持的两种IO隔离策略 .1. (Completely Fair Queuing 完全公平队列)cfq io调度策略,支持按权重 ...
- The `XXXX` target overrides the `HEADER_SEARCH_PATHS` build setting defined in `Pods/Target Support Files/Pods-game-desktop/Pods-game-desktop.release.xcconfig'. This can lead to prob
The `game-desktop [Release]` target overrides the `HEADER_SEARCH_PATHS` build setting defined in `Po ...
- Chris Richardson微服务翻译:微服务架构中的服务发现
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...
- laravel ORM 命令2
一.查询 获取数据库所有数据 Model::all() 获取指定条件数据 Modle::where('status','1')->get() 获取第一条数据 Model::where('stat ...
- MyBatis + MySQL返回插入的主键id
这是最近在实现perfect-ssm中的一个功能时碰到的一个小问题,觉得需要记录一下,向MySQL数据库中插入一条记录后,需要获取此条记录的id值,以生成对应的key值存入到redis中,id为自增i ...