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, );
- }
- #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, ) == true)
- {
- MessageDxUtil.ShowTips("Internet网络连通!");
- }
- else
- {
- MessageDxUtil.ShowTips("Internet网络不通!");
- }
- }
C#调用C++动态库(dll)的更多相关文章
- 在VS2015中用C++编写可被其它语言调用的动态库DLL
转自:http://blog.csdn.net/songyi160/article/details/50754705 VS2015用C++创建动态库DLL步骤如下: (1)启动VS2015>文件 ...
- C++与C#有关对库(动态库dll,静态库.lib)文件的调用
1 动态库的相互调用 1.1 C#调用C++ dll步骤(只能导出方法): 1. c++建立空项目->源文件文件夹中添加cpp文件和函数 2. c++属性设置中,配置类型设置为动态库dll,公共 ...
- Qt生成和调用动态库dll,和静态库.a(windows和linux通用)
系统1:ThinkPad T570.Windows10.QT5.12.2(Qt Creater 4.8.2)一.动态库.dll的创建和调用1.在qtcreater中按如下步骤创建动态库,动态库名为my ...
- c#调用c++动态库的一些理解
调用c++动态库一般我们这样写 [DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)] ...
- C#总结(四)调用C++动态库
由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...
- 【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++中间件动态库 ...
- 五,动态库(dll)的封装与使用
在项目开发中,我们经常会使用到动态库(dll),要么是使用别人的动态库,要么是将功能函数封装为动态库给别人用.那么如何封装和使用动态库呢?以下内容为你讲解. 1.动态库的封装 以vs2010为例,我们 ...
随机推荐
- SqlSugar框架T4模板的使用
一.T4模板说明 1.T4模板是用来生成Model层实体类的 2.文件后缀为.tt 3.需要修改配置主要有:引用的SqlSugar.dll的位置.生成实体类的位置及生成实体类的命名空间 4.T4模板生 ...
- CSV文件规则
CSV文件规则 1 开头是不留空,以行为单位.2 可含或不含列名,含列名则居文件第一行.3 一行数据不跨行,无空行.4 以半角逗号(即,)作分隔符,列为空也要表达其存在.5 列内容如存在半角逗号(即, ...
- HTML网页图片滚动代码
<!--下面是向上滚动代码--> <div id=butong_net_top style=overflow:hidden;height:100;width:90;> < ...
- SGU 269. Rooks(DP)
题意: 给n(<=250)条水平网格,然后在上面放k棋子,每行每列都只能放一个.求方法总数. Solution: 简单的DP, 只要对给出的水平长度排个序就很容易处理了. 需要用到高精度. 偷懒 ...
- C++类型转换总结 转
一.前言: C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a. C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. con ...
- 开启 htaccess 配置
是在wamp中,apache2.2 开启 伪静态时,httpd.conf 配置如下: 查找 <Directory />Options FollowSymLinksAllowOverride ...
- JavaScript学习总结【5】、JS DOM
1.DOM 简介 当页面加载时,浏览器会创建页面的文档对象模型(Document Object Model).文档对象模型定义访问和处理 HTML 文档的标准方法.DOM 将 HTML 文档呈现为带有 ...
- HTML5-javascript屏幕旋转事件:onorientationchange
屏幕旋转事件:onorientationchange 添加屏幕旋转事件侦听,可随时发现屏幕旋转状态(左旋.右旋还是没旋) 判断屏幕是否旋转 function orientationChange() { ...
- TensorFlow和最近发布的slim
笔者将和大家分享一个结合了TensorFlow和最近发布的slim库的小应用,来实现图像分类.图像标注以及图像分割的任务,围绕着slim展开,包括其理论知识和应用场景. 之前自己尝试过许多其它的库,比 ...
- AngularJS学习-初识
angularJS定义和特点 1.google前端开源框架 2.MVVM(model view view-model)设计模式 : Model将和ViewModel互动(通过$scope对象),将监听 ...