在实际软件开发过程中,由于公司使用了多种语言开发,在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)相关推荐

  1. java调用c so动态库_jni 调用C动态库dll/so

    http://hi.baidu.com/fengying765/blog/item/7081113e5fde53e555e7233f.html 作为主调方的Java源程序TestJNI.java如下. ...

  2. C#.net调用动态库dll注意事项

    C#.net调用动态库dll注意事项 本文主要描述作者在工作中所遇到技术难点及问题,最后提出相关的解决方案 场景 公司有个业务需求涉及到ID读卡器,构建成在ID卡读卡器一刷ID卡,系统就自动显示其ID ...

  3. c 调用c语言写的dll文件路径,手把手教你用C/C++语言创建及调试动态库DLL程序

    引子 动态链接库DLL文件不仅可以实现代码.资源和数据的共享,同时也可以对源代码起保护作用,对于开发者来讲,DLL的生成及调试是程序员必须掌握的一种技术,下面通过一个具体的例子,演示使用C/C++语言 ...

  4. C#总结:C#调用C++的动态库Dll遇到的问题[动态库调用/结构体指针调用/union共同体定义]

    记录使用C#调用C++的生成的DLL手柄键盘驱动库包括****.sys(驱动文件)和****.dll(库文件)的全部问题. C#调用C++的库有两种:静态调用和动态调用 静态调用,使用.net 提供的 ...

  5. java调用C或者C++动态库dll

    java调用C或者C++动态库dll,本文章使用的是IntelliJ IDEA Community Edition 2021.2.3版本测试的 1.新建项目 linjie.demo,添加类HelloL ...

  6. C# VC6调用VC6的动态库DLL

    C# VC6调用VC6的动态库DLL 一 VC创建动态库 1. DLL的创建 启动VC6.0, 新建一个"Win32 Dynamic-Link Library"工程,选择" ...

  7. python调用.net动态库

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

  8. C#总结(四)调用C++动态库

    由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...

  9. Qt调用CUDA动态库及配置

    本文配置环境:Win7(x64)+VS2012+CUDA+Qt5.5.0 1.首先保证CUDA集成到VS下(如下图顺利安装Nsight for VS2012).CUDA安装比较简单,选自定义安装,然后 ...

最新文章

  1. ASP.NET JScript公共类(非常有用)
  2. android 动画 最顶层_【Android编程实战】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗...
  3. 被一帮小姐姐围着是什么感觉?
  4. django 1.8 官方文档翻译: 2-5-10 数据库函数
  5. CTS(23)---Camera Media CTS GTS VTS 记录
  6. 中兴通讯推出全球首款Wi-Fi 7标准5G CPE
  7. Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)
  8. scrapy.request
  9. Pycharm远程链接矩池云报错踩坑记录
  10. 《统计学习方法》——逻辑斯蒂回归
  11. soapUI 接口测试断言
  12. lsb隐写的基本方法matlab,GitHub - RGNil/RG_LSB: 利用python实现LSB隐写算法(我自己改进了LSB算法),并进行了性能分析(psnr、错误率、鲁棒性)...
  13. 微信公众平台测试账号申请地址
  14. 十分钟学会如何用Python处理CSV文件
  15. 《工程学导论》读后感
  16. 【影音工具集合】本文记录了影音工作者常用的好用的工具软件(持续更新中)
  17. hach vue 跳转_Vue路由实现、路由导航、路由模式
  18. Python正则re模块详解
  19. m=m++到底发生了什么
  20. 大学计算机长文档排版教学视频教程,大学计算机基础中Word长文档排版的教学思考...

热门文章

  1. 3-15 《元编程》第6章 3-16 hook method
  2. /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15 not found
  3. git clone时出现 error:inflate:data stream error(incorrect data check)
  4. 在使用多表的查询显示的时候 建议使用视图
  5. Hibernate映射关系总结篇
  6. 在欲而无欲,居尘不染尘
  7. iOS之页面布局-踩坑的原由
  8. MySQL触发器(转载)
  9. Tomcat 配置Https
  10. javascript使用btoa和atob来进行Base64转码和解码