综述 : 本文章介绍.Net 环境下C# 通过托管C++调用本地C++ Dll文件, 示例环境为:VS2010, .Net4.0, Win7. 具体事例为测试C++, C#, 及C#调用本地C++Dll文件进行浮点运算效率的一部分. 如果需要查看三者的效率, 请继续阅读下面的文章.

a 创建本地CPP类库

1. 创建本地CPP的Dll ---->EfficiencyNativeCPPDLL

2. 点击下一步 注意选择为DLL(D)项, 然后选择完成.

3.书写DLL文件

3.1

  1. EfficiencyNativeCppDll.h
  2.  
  3. #pragma once
  4.  
  5. #ifndef GoWin_DLL_CLASS_EXPORTS
  6. //该类可导出
  7. #define GoWin_DLL_CLASS __declspec(dllexport)
  8. #else
  9. //该类可导入
  10. #define GoWin_DLL_CLASS __declspec(dllimport)
  11. #endif
  12. #define NPARTS 1000
  13. #define DIMS 3
  14.  
  15. class GoWin_DLL_CLASS EfficiencyNativeCppDll
  16. {
  17. public:
  18. EfficiencyNativeCppDll(void);
  19. ~EfficiencyNativeCppDll(void);
  20.  
  21. void InitPositions();
  22. void UpdatePositions();
  23. double ComputePot();
  24. double Pot;
  25. private:
  26. double _r[DIMS][NPARTS];
  27. };

3.2

  1. EfficiencyNativeCppDll.cpp
  2.  
  3. #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <math.h>
  8. #include <time.h>
  9.  
  10. EfficiencyNativeCppDll::EfficiencyNativeCppDll(void)
  11. {
  12. Pot = 0;
  13. }
  14.  
  15. EfficiencyNativeCppDll::~EfficiencyNativeCppDll(void)
  16. {
  17. printf("~EfficiencyNativeCppDll is called");
  18. }
  19.  
  20. void EfficiencyNativeCppDll::InitPositions()
  21. {
  22. for(int i = 0; i < DIMS; i++)
  23. {
  24. for (int j = 0; j < NPARTS; j++)
  25. {
  26. _r[i][j] = 0.5 + (double)rand()/RAND_MAX;
  27. }
  28. }
  29. }
  30.  
  31. void EfficiencyNativeCppDll::UpdatePositions()
  32. {
  33. for(int i = 0; i < DIMS; i++)
  34. {
  35. for (int j = 0; j < NPARTS; j++)
  36. {
  37. _r[i][j] -= 0.5 + (double)rand()/RAND_MAX;
  38. }
  39. }
  40. }
  41.  
  42. double EfficiencyNativeCppDll::ComputePot()
  43. {
  44. double distx, disty, distz, dist;
  45. double pot;
  46. distx = 0;
  47. disty = 0;
  48. distz = 0;
  49. pot = 0;
  50.  
  51. for(int i=0; i<NPARTS; i++ )
  52. {
  53. for(int j=0; j<i-1; j++ )
  54. {
  55. distx = pow( (_r[0][j] - _r[0][i]), 2 );
  56. disty = pow( (_r[1][j] - _r[1][i]), 2 );
  57. distz = pow( (_r[2][j] - _r[2][i]), 2 );
  58. dist = sqrt( distx + disty + distz );
  59. pot += 1.0 / dist;
  60. }
  61. }
  62.  
  63. this->Pot = pot;
  64.  
  65. return pot;
  66. }

在Release状态下生成, 会得到 EfficiencyNativeCPPDLL.dll 和 EfficiencyNativeCPPDLL.lib两种文件 其中EfficiencyNativeCPPDLL.dll用于后面的CLR/C++调用; 而EfficiencyNativeCPPDLL.lib则用于Native C++的调用; 这在效率对比一文中会用到.

b 创建C++/CLI类库

1. 添加新建项目 EfficiencyCLRWrapper

2. 项目 EfficiencyCLRWrapper需要对项目EfficiencyNativeCPPDLL中的EfficiencyNativeCppDll.h 和 EfficiencyCLRWrapper.dll引用

2.1 引用EfficiencyNativeCppDll.h

有两种方式, 可任选一种

a) 将EfficiencyNativeCppDll.h直接复制到 项目 EfficiencyCLRWrapper中, 这很简单 不再描述

b)  更改 项目 EfficiencyCLRWrapper属性设置中包换目录选项, 以包含文件EfficiencyNativeCppDll.h

b.1) 看到右侧的包含目录了吗? 点击后选择 编辑

b.2)   我这里选择了把EfficiencyNativeCPPDLL文件夹及项目EfficiencyNativeCPPDLL的Release文件夹均包含在内了

2.2 引用完成后书写C++/CLR代码

2.2.1 头文件

  1. EfficiencyCLRWrapper.h
  2.  
  3. #pragma once
  4. #include "EfficiencyNativeCppDll.h"
  5. #define GoWin_DLL_CLASS
  6.  
  7. using namespace System;
  8.  
  9. namespace EfficiencyCLRWrapper {
  10.  
  11. public ref class CLRWrapper
  12. {
  13. private:
  14. EfficiencyNativeCppDll * _pNtvCppPro;
  15. public:
  16. CLRWrapper(void);
  17. ~CLRWrapper(void);
  18. void InitPositions();
  19. void UpdatePositions();
  20. double ComputePot();
  21. property double Pot
  22. {
  23. double get();
  24. void set(double value);
  25. }
  26. };
  27. }

2.2.2 主体文件

  1. #include "EfficiencyCLRWrapper.h"
  2. using namespace EfficiencyCLRWrapper;
  3.  
  4. CLRWrapper::CLRWrapper(){ this->_pNtvCppPro = new EfficiencyNativeCppDll();}
  5. CLRWrapper::~CLRWrapper(){}
  6.  
  7. double CLRWrapper::ComputePot()
  8. {
  9. return this->_pNtvCppPro->ComputePot();
  10. }
  11.  
  12. void CLRWrapper::InitPositions()
  13. {
  14. this->_pNtvCppPro->InitPositions();
  15. }
  16.  
  17. void CLRWrapper::UpdatePositions()
  18. {
  19. this->_pNtvCppPro->UpdatePositions();
  20. }
  21.  
  22. double CLRWrapper::Pot::get()
  23. {
  24. return this->_pNtvCppPro->Pot;
  25. }
  26.  
  27. void CLRWrapper::Pot::set(double value)
  28. {
  29. this->_pNtvCppPro->Pot = value;
  30. }

2.2.3 将形成如下树结构:

3. 千万不要忘记的一点就是在项目EfficiencyCLRWrapper中对EfficiencyNativeCPPDLL的引用, 否则依旧无法生成, 如图:

4 这个时候 对项目EfficiencyCLRWrapper在Release下生成则可以得到 文件 CLRCPPWrapper.dll

C 创建C# 控制台应用程序

1 添加C#项目 ConsoleEfficiencyCSInvokeCLRDll

2.  添加对项目 EfficiencyCLRWrapper的引用
     

3. 因项目ConsoleEfficiencyCSInvokeCLRDll须间接调用EfficiencyNativeCPPDLL.dll因此 跟上面相同可用两种方法解决

可任选其一

a) 将以生成的EfficiencyNativeCPPDLL.dll复制到项目ConsoleEfficiencyCSInvokeCLRDll的bin/Release文件夹下 不再具体描述

b) 添加项目ConsoleEfficiencyCSInvokeCLRDll属性中调试中的工作目录 如图:

4.  在Program.cs文件中做CS的调用

  1. namespace EfficiencyCSInvokeCLRDll
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. CLRWrapper provider = new CLRWrapper();
  8. const int NITER = 201;
  9.  
  10. provider.InitPositions();
  11. provider.UpdatePositions();
  12.  
  13. int start = Environment.TickCount;
  14. for (int i = 0; i < NITER; i++)
  15. {
  16. provider.Pot = 0.0;
  17.  
  18. //低效模式
  19. /*provider.ComputePot();
  20. if (i % 10 == 0)
  21. Console.WriteLine("{0}: Potential: \t {1}", i, provider.Pot());
  22. */
  23.  
  24. //高效模式
  25. if (i % 10 == 0)
  26. Console.WriteLine("{0}: Potential: \t {1}", i, provider.ComputePot());
  27. provider.UpdatePositions();
  28.  
  29. }
  30. int stop = Environment.TickCount;
  31.  
  32. Console.WriteLine("Seconds = {0,10}", (double)(stop - start) / 1000);
  33.  
  34. Console.ReadKey();
  35. }
  36. }
  37. }

运行结果:

结果一般在0.240至00.281之间

硬件环境:  Inter(R) Core(TM)2 Duo CPU P8700 @ 2.53GHz 2.53GHz RAM 共4G(2.46GB可用)

疑问:

这里面有两点疑问

1. 在CS调用中标出的高效模式和低效模式; 无非一个是直接调用函数返回值一个是调用函数后读取属性, 但是执行效率相差接近10倍.

2. 在C++/CLR中红色表示的构造函数中申请的内存不晓得何时释放.

.Net 环境下C# 通过托管C++调用本地C++ Dll文件的更多相关文章

  1. $ npm install opencv ? 你试试?! 在windows环境下,使用node.js调用opencv攻略

    博主之前写过一篇文章<html5与EmguCV前后端实现——人脸识别篇>,叙述的是opencv和C#的故事.最近在公司服务器上更新了一套nodejs环境,早就听闻npm上有opencv模块 ...

  2. vs2010下C++调用lib或dll文件

    注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1  设置工程的 ...

  3. win10环境下使用苹果虚拟机不要开多线程应用下载文件

    win10环境下使用苹果虚拟机开多线程应用下载文件时候卡死,网络老掉. 8GB内存不够用?2.5mb网速不够用? 开的百度网盘下载个电影 结果虚拟机卡的不行 关了 网盘 挂起虚拟机 然后再 继续运行客 ...

  4. Centos7环境下使用Nginx托管.Net Core应用程序

    一.安装.Net Core 参考官方文档:https://www.microsoft.com/net/core#linuxcentos 1.添加dotnet产品Feed 在安装.NET Core之前, ...

  5. LNMP环境下独立安装Mysql5.7.18 并对数据库文件进行本地物理迁移 (需暂停数据库服务方式)

    前几天读研时候的同学要我帮忙给解决一个问题,就是Redhat服务器下面安装了LNMP,并且由于分区的划分不当导致MySQL数据库中存放数据库的盘区内空间被急剧消耗,由于该应用主要是数据分析及备份所用, ...

  6. ffi模块——node调用动态链接库(.so/.dll文件)

    参考资料1:[https://www.npmjs.com/package/ffi] 参考资料2:[http://imweb.io/topic/57732fbef0a5487b05f325bf] 参考资 ...

  7. iOS 在 ARC 环境下 dealloc 的使用、理解误区

    iOS 在 ARC 环境下 dealloc 的使用.理解误区 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致&qu ...

  8. Linux环境下编译并执行ava helloworld程序

    原文:http://blog.lupaworld.com/home-space-uid-24466-do-blog-id-2578.html 已经学会怎样在Windows下怎样编辑,编译和运行Java ...

  9. nodejs 修改端口号 process.env.PORT(window环境下)

    各个环境下,nodejs设置process.env.PORT的值的命令,如下1.linux环境下: PORT= node app.js 使用上面命令每次都需要重新设置,如果想设置一次永久生效,使用下面 ...

随机推荐

  1. Java给图片和PDF文件添加水印(图片水印和文字水印)

    有时候我们看到的图片或者PDF文件会自动加上水印.分为文字水印和图片水印. ----------------------------图片水印---------------------------- 1 ...

  2. arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf等的区别【转】

    转自:https://www.cnblogs.com/deng-tao/p/6432578.html 博客来之于:  http://www.veryarm.com/296.html 交叉编译工具链的命 ...

  3. 抓包获取百度音乐API

    这次抓包是获取手机APP中的数据包,共分为三个部分: 1.win7建立wifi 2.PC架设代理服务器 手机设置代理 3.抓包分析 一.win7建立wifi 在win7下搭建wifi非常简单,网上的教 ...

  4. 从零开始自己搭建复杂网络(以Tensorflow为例)

    从零开始自己搭建复杂网络(以MobileNetV2为例) tensorflow经过这几年的发展,已经成长为最大的神经网络框架.而mobileNetV2在经过Xception的实践与深度可分离卷积的应用 ...

  5. mysql 用init-connect+binlog实现用户操作追踪做access的ip的log记录

    在MYSQL中,每个连接都会先执行init-connect,进行连接的初始化.我们可以在这里获取用户的登录名称和thread的ID值.然后配合binlog,就可以追踪到每个操作语句的操作时间,操作人等 ...

  6. hadoop-2.7.2-HA安装笔记

    配置方案如图   NN DN ZK ZKFC JN RM NM(任务管理器) HMaster Region Server Node1 1 1 1 1 1 Node2 1 1 1 1 1 1 1 Nod ...

  7. SQL语句导致性能问题

    前阵子,突然收到服务器的报警信息,于是上服务器找问题,我擦,top看到mysql占的%cpu高得把我吓尿了 从以上的信息看,相信大家已经可以定位到底是那个程序导致服务器CPU负载过高了,但我们要做的是 ...

  8. NET-知识点:C#中Equals和==比较

    第一.相等性比较 其实这个问题的的本质就是C#的相等比较,相等比较可以分两类: 1.引用相等性,引用相等性指两个对象引用均引用同一基础对象. 2.值相等性,值相等性指两个对象包含相同的一个或多个值,其 ...

  9. 慢查询日志和profiling

    MySQL调优三步: 慢查询 (分析出现出问题的sql) Explain (显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句) Profile ...

  10. SSL证书链说明

    SSL证书链说明 1. SSL证书链定义 证书颁发机构(CA)共分为两种类型:根CA和中间CA.为了使SSL证书被信任,该证书必须由设备所连接的可信存储库CA颁发. 如果该证书不是由受信任CA,该链接 ...