C# : 调用C++动态库(dll)
在实际软件开发过程中,由于公司使用了多种语言开发,在C#中可能需要实现某个功能,而该功能可能用其他语言已经实现了,那么我们可以调用其他语言写好的模块吗?还有就是,由于C#开发好的项目,我们可以利用reflector等反编译工具反编译出其源代码,所以对于一些核心算法,我们不希望被别人知道,因此为了增强代码的安全性,我们需要将一些核心算法用C或C++来编写,然后用C#来调用这些已经写好的接口。在面对以上情况时,我们该怎么做呢?
方案一:重新实现
针对第一种情况,我们可以将C或者C++功能用C#来重新实现,这样的话代码比较统一,维护比较方便,但是这样的话增加了软件开发的成本,把C++的代码功能改成C#涉及到指针和内存的操作比较繁琐,况且有开发好的模块为什么不重复利用呢?针对第二种情况就不能得到有效解决,虽然可以使用混淆器对代码进行混淆,但是任然不是很安全。
方案二:封装COM组件
我们可以将C或者C++的函数封装成COM组件,在C#中调用时比较方便,但是COM组件需要注册,而且多次注册可能也会导致一些问题,同时在处理C或者C++的类型与COM组件的类型转换的时候也可能有些麻烦。
方案三:使用动态链接库
我们可以直接调用C或者C++已经写好的动态链接库,这样比较方便,这样很好的解决了上述问题。
在实际项目中,我们需要使用C#调用C++的一些接口,因此我使用的是方案三采用动态库,下面我就在实际中怎么处理的进行说明。
在调用动态库的过程中我也遇到了以下一些问题:
1、C++中有指针,C#中需要使用指针吗?
由于C++中的动态库中有指针参数,因此我也是用.NET的不安全代码,使用了C#的指针,但是最后也还是出现了一些问题,如在C#中传入的参数是一个二维数组时就出现了问题,这个问题我在网上找了好多资料也没有解决,最后和c++程序员商量了下改变了传入参数的参数类型。最后也没有使用指针。
2、C#和C++中的类型如何转换呢?
虽然C#和C++比较类似,但是其给我们的参数类型我们要与C#的参数类型一一对应起来,因此我找了一些资料把其类型一一对应了,具体看后续说明。
3、C++写好的动态库放到那个位置呢?
关于C++动态库的位置也是个问题,在应用中我们使用了相对路径和绝对路径进行测试,有的发现在VS中可以调用到,但是发布后发现无法调用到动态库,最后只要把动态的dll放到系统的目录system32下面才解决了改问题,目前还没找到其他的方法,如有其他的更好方法还请大家指点。
4、如何反编译C++的dll的名称,端口?
可以通过Dependency Walker工具进行反编译查看别人写的动态库的信息
5、还有其他的一些细节,如C#调用动态库需要指定其编码、代码写法等等
c#调用c++动态库一般我们这样写
[DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)]
public extern static void Disp_Destroy(IntPtr hShow);
DllImport的第一个参数UCamer.dll是动态库dll的路径,此dll放在程序运行的根目录或者c:windows/sytem32下
CallingConvention 参数是c#调用c++的方式 是个枚举 msdn解释如下
Cdecl | 调用方清理堆栈。这使您能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。 |
FastCall | 不支持此调用约定。 |
StdCall | 被调用方清理堆栈。这是使用平台 invoke 调用非托管函数的默认约定。 |
ThisCall | 第一个参数是 this 指针,它存储在寄存器 ECX 中。其他参数被推送到堆栈上。此调用约定用于对从非托管 DLL 导出的类调用方法。 |
Winapi | 此成员实际上不是调用约定,而是使用了默认平台调用约定。例如,在 Windows 上默认为 StdCall,在 Windows CE.NET 上默认为 Cdecl。 |
从上面来看Winapi方式是根据系统自动选择调用规约的。 而thisCall是对c++类的调用方法。 所以 一般情况下我们选择Winapi就可以了。
例子:
#region 无标题窗体右键任务栏弹出菜单代码[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]public static extern int GetWindowLong(HandleRef hWnd, int nIndex);[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]public static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);protected override CreateParams CreateParams{get{const int WS_MINIMIZEBOX = 0x00020000; // Winuser.h中定义 CreateParams cp = base.CreateParams;cp.Style = cp.Style | WS_MINIMIZEBOX; // 允许最小化操作 return cp;}}#endregion#region 窗体拖动代码[DllImport("user32.dll")]public static extern bool ReleaseCapture();[DllImport("user32.dll")]public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);public const int WM_SYSCOMMAND = 0x0112;public const int SC_MOVE = 0xF010;public const int HTCAPTION = 0x0002;private void Login_MouseDown(object sender, MouseEventArgs e){ReleaseCapture();SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);}#endregion[DllImport("wininet.dll")]private extern static bool InternetGetConnectedState(out int conn, int val);private void btnNetTest_Click(object sender, EventArgs e){int Out;if (InternetGetConnectedState(out Out, 0) == true){MessageDxUtil.ShowTips("Internet网络连通!");}else{MessageDxUtil.ShowTips("Internet网络不通!");}}
C# : 调用C++动态库(dll)相关推荐
- java调用c so动态库_jni 调用C动态库dll/so
http://hi.baidu.com/fengying765/blog/item/7081113e5fde53e555e7233f.html 作为主调方的Java源程序TestJNI.java如下. ...
- C#.net调用动态库dll注意事项
C#.net调用动态库dll注意事项 本文主要描述作者在工作中所遇到技术难点及问题,最后提出相关的解决方案 场景 公司有个业务需求涉及到ID读卡器,构建成在ID卡读卡器一刷ID卡,系统就自动显示其ID ...
- c 调用c语言写的dll文件路径,手把手教你用C/C++语言创建及调试动态库DLL程序
引子 动态链接库DLL文件不仅可以实现代码.资源和数据的共享,同时也可以对源代码起保护作用,对于开发者来讲,DLL的生成及调试是程序员必须掌握的一种技术,下面通过一个具体的例子,演示使用C/C++语言 ...
- C#总结:C#调用C++的动态库Dll遇到的问题[动态库调用/结构体指针调用/union共同体定义]
记录使用C#调用C++的生成的DLL手柄键盘驱动库包括****.sys(驱动文件)和****.dll(库文件)的全部问题. C#调用C++的库有两种:静态调用和动态调用 静态调用,使用.net 提供的 ...
- java调用C或者C++动态库dll
java调用C或者C++动态库dll,本文章使用的是IntelliJ IDEA Community Edition 2021.2.3版本测试的 1.新建项目 linjie.demo,添加类HelloL ...
- C# VC6调用VC6的动态库DLL
C# VC6调用VC6的动态库DLL 一 VC创建动态库 1. DLL的创建 启动VC6.0, 新建一个"Win32 Dynamic-Link Library"工程,选择" ...
- python调用.net动态库
# python调用.net动态库 ### pythonnet简介 ----------------------------- - pythonnet是cpython的扩展 - pythonnet提供 ...
- C#总结(四)调用C++动态库
由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...
- Qt调用CUDA动态库及配置
本文配置环境:Win7(x64)+VS2012+CUDA+Qt5.5.0 1.首先保证CUDA集成到VS下(如下图顺利安装Nsight for VS2012).CUDA安装比较简单,选自定义安装,然后 ...
最新文章
- ASP.NET JScript公共类(非常有用)
- android 动画 最顶层_【Android编程实战】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗...
- 被一帮小姐姐围着是什么感觉?
- django 1.8 官方文档翻译: 2-5-10 数据库函数
- CTS(23)---Camera Media CTS GTS VTS 记录
- 中兴通讯推出全球首款Wi-Fi 7标准5G CPE
- Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)
- scrapy.request
- Pycharm远程链接矩池云报错踩坑记录
- 《统计学习方法》——逻辑斯蒂回归
- soapUI 接口测试断言
- lsb隐写的基本方法matlab,GitHub - RGNil/RG_LSB: 利用python实现LSB隐写算法(我自己改进了LSB算法),并进行了性能分析(psnr、错误率、鲁棒性)...
- 微信公众平台测试账号申请地址
- 十分钟学会如何用Python处理CSV文件
- 《工程学导论》读后感
- 【影音工具集合】本文记录了影音工作者常用的好用的工具软件(持续更新中)
- hach vue 跳转_Vue路由实现、路由导航、路由模式
- Python正则re模块详解
- m=m++到底发生了什么
- 大学计算机长文档排版教学视频教程,大学计算机基础中Word长文档排版的教学思考...
热门文章
- 3-15 《元编程》第6章 3-16 hook method
- /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15 not found
- git clone时出现 error:inflate:data stream error(incorrect data check)
- 在使用多表的查询显示的时候 建议使用视图
- Hibernate映射关系总结篇
- 在欲而无欲,居尘不染尘
- iOS之页面布局-踩坑的原由
- MySQL触发器(转载)
- Tomcat 配置Https
- javascript使用btoa和atob来进行Base64转码和解码