由于公司很多底层的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++动态库的更多相关文章

  1. .netcore在linux下使用P/invoke方式调用linux动态库

    http://www.mamicode.com/info-detail-2358309.html   .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...

  2. c#调用c++动态库的一些理解

    调用c++动态库一般我们这样写   [DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)] ...

  3. C#调用C++动态库(dll)

    在实际软件开发过程中,由于公司使用了多种语言开发,在C#中可能需要实现某个功能,而该功能可能用其他语言已经实现了,那么我们可以调用其他语言写好的模块吗?还有就是,由于C#开发好的项目,我们可以利用re ...

  4. Java调用dll动态库

    最近项目里使用java调用dll动态库,因此研究了一下这方面的东西. 使用的工具包如下 <dependency> <groupId>net.java.dev.jna</g ...

  5. 【C#】 使用Gsof.Native 动态调用 C动态库

    [C#] 使用Gsof.Native 动态调用 C动态库 一.背景 使用C# 开发客户端时候,我们经常会调用一些标准的动态库或是C的类库.虽然C# 提供的PInvoke的方式,但因为使用的场景的多变, ...

  6. python调用.net动态库

    # python调用.net动态库 ### pythonnet简介------------------------------ pythonnet是cpython的扩展- pythonnet提供了cp ...

  7. Delphi XE7调用C++动态库出现乱码问题回顾

    事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...

  8. 使用ctypes在Python中调用C++动态库

    使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #in ...

  9. C# 调用C++动态库注意事项

    C# 调用C++动态库注意事项 最近项目上需要在C#中调用C++,期间遇到不少坑,总结如下: 1.in const char*   对应C#中string 或  IntPtr 2.out const ...

随机推荐

  1. 关于Python的函数(Method)与方法(Function)

    先上结论: 函数(function)是Python中一个可调用对象(callable), 方法(method)是一种特殊的函数. 一个可调用对象是方法和函数,和这个对象无关,仅和这个对象是否与类或实例 ...

  2. HTTPS、证书与使用Charles抓包

    .p1 { margin: 0.0px 0.0px 0.0px 0.0px; font-size: 14.0px; font-family: "Helvetica Neue", & ...

  3. Go从三个站点中返回响应最快的

    利用协程可以轻松实现 package main import ( "fmt" "github.com/imroc/req" ) func mirroredQue ...

  4. 阿里mysql同步工具otter的docker镜像

    https://github.com/dearplain/otter_manager https://github.com/dearplain/otter_node 本人开发的小巧docker镜像,根 ...

  5. python之pyqt4的简单窗口布局以及信号和槽(上代码)

    #-*- coding: utf-8 -*- import sys reload(sys) sys.setdefaultencoding('utf8') from PyQt4 import QtGui ...

  6. QA: 自闭合标签要不要手动闭合?

    起 自闭合标签末尾要不要加 /,这个问题一直 "困扰" 着我.但是抱着无所谓的态度,一直没有仔细去看下. 以 img 标签为例,一般有以下三种写法: <img src=&qu ...

  7. Linux audio驱动模型

    linux驱动 alsa模型: Linux ALSA声卡驱动之一:ALSA架构简介 Linux ALSA声卡驱动之二:声卡的创建 Linux ALSA声卡驱动之三:PCM设备的创建 Linux ALS ...

  8. ogg的孩子-无损音频编解码flac

    flac是一款无损的音频压缩编码,它的特点是对音频文件进行无损压缩,目前是被很多软件及智能硬件产品所支持. 从技术上来讲,该编解码的优点还是十分明显的,无损压缩,策略灵活,解码快速,硬件支持等特点都是 ...

  9. python模块安装

    现在终于知道怎么在windows上导入Python的第三方模块了 首先在DOS下进入Python安装的pip目录:D:/Python27/Scripts 用pip install XXX安装 之前一直 ...

  10. Javascrip随笔1

    isNaN:指示某个值不是数字 文本字符串中使用反斜杠对代码行进行换行; 在计算机程序中,经常会声明无值的变量.未使用值来声明的变量,其值实际上是 undefined.在执行过以下语句后,变量 car ...