.Net 环境下C# 通过托管C++调用本地C++ Dll文件
综述 : 本文章介绍.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
- EfficiencyNativeCppDll.h
- #pragma once
- #ifndef GoWin_DLL_CLASS_EXPORTS
- //该类可导出
- #define GoWin_DLL_CLASS __declspec(dllexport)
- #else
- //该类可导入
- #define GoWin_DLL_CLASS __declspec(dllimport)
- #endif
- #define NPARTS 1000
- #define DIMS 3
- class GoWin_DLL_CLASS EfficiencyNativeCppDll
- {
- public:
- EfficiencyNativeCppDll(void);
- ~EfficiencyNativeCppDll(void);
- void InitPositions();
- void UpdatePositions();
- double ComputePot();
- double Pot;
- private:
- double _r[DIMS][NPARTS];
- };
3.2
- EfficiencyNativeCppDll.cpp
- #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <time.h>
- EfficiencyNativeCppDll::EfficiencyNativeCppDll(void)
- {
- Pot = 0;
- }
- EfficiencyNativeCppDll::~EfficiencyNativeCppDll(void)
- {
- printf("~EfficiencyNativeCppDll is called");
- }
- void EfficiencyNativeCppDll::InitPositions()
- {
- for(int i = 0; i < DIMS; i++)
- {
- for (int j = 0; j < NPARTS; j++)
- {
- _r[i][j] = 0.5 + (double)rand()/RAND_MAX;
- }
- }
- }
- void EfficiencyNativeCppDll::UpdatePositions()
- {
- for(int i = 0; i < DIMS; i++)
- {
- for (int j = 0; j < NPARTS; j++)
- {
- _r[i][j] -= 0.5 + (double)rand()/RAND_MAX;
- }
- }
- }
- double EfficiencyNativeCppDll::ComputePot()
- {
- double distx, disty, distz, dist;
- double pot;
- distx = 0;
- disty = 0;
- distz = 0;
- pot = 0;
- for(int i=0; i<NPARTS; i++ )
- {
- for(int j=0; j<i-1; j++ )
- {
- distx = pow( (_r[0][j] - _r[0][i]), 2 );
- disty = pow( (_r[1][j] - _r[1][i]), 2 );
- distz = pow( (_r[2][j] - _r[2][i]), 2 );
- dist = sqrt( distx + disty + distz );
- pot += 1.0 / dist;
- }
- }
- this->Pot = pot;
- return pot;
- }
在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 头文件
- EfficiencyCLRWrapper.h
- #pragma once
- #include "EfficiencyNativeCppDll.h"
- #define GoWin_DLL_CLASS
- using namespace System;
- namespace EfficiencyCLRWrapper {
- public ref class CLRWrapper
- {
- private:
- EfficiencyNativeCppDll * _pNtvCppPro;
- public:
- CLRWrapper(void);
- ~CLRWrapper(void);
- void InitPositions();
- void UpdatePositions();
- double ComputePot();
- property double Pot
- {
- double get();
- void set(double value);
- }
- };
- }
2.2.2 主体文件
- #include "EfficiencyCLRWrapper.h"
- using namespace EfficiencyCLRWrapper;
- CLRWrapper::CLRWrapper(){ this->_pNtvCppPro = new EfficiencyNativeCppDll();}
- CLRWrapper::~CLRWrapper(){}
- double CLRWrapper::ComputePot()
- {
- return this->_pNtvCppPro->ComputePot();
- }
- void CLRWrapper::InitPositions()
- {
- this->_pNtvCppPro->InitPositions();
- }
- void CLRWrapper::UpdatePositions()
- {
- this->_pNtvCppPro->UpdatePositions();
- }
- double CLRWrapper::Pot::get()
- {
- return this->_pNtvCppPro->Pot;
- }
- void CLRWrapper::Pot::set(double value)
- {
- this->_pNtvCppPro->Pot = value;
- }
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的调用
- namespace EfficiencyCSInvokeCLRDll
- {
- class Program
- {
- static void Main(string[] args)
- {
- CLRWrapper provider = new CLRWrapper();
- const int NITER = 201;
- provider.InitPositions();
- provider.UpdatePositions();
- int start = Environment.TickCount;
- for (int i = 0; i < NITER; i++)
- {
- provider.Pot = 0.0;
- //低效模式
- /*provider.ComputePot();
- if (i % 10 == 0)
- Console.WriteLine("{0}: Potential: \t {1}", i, provider.Pot());
- */
- //高效模式
- if (i % 10 == 0)
- Console.WriteLine("{0}: Potential: \t {1}", i, provider.ComputePot());
- provider.UpdatePositions();
- }
- int stop = Environment.TickCount;
- Console.WriteLine("Seconds = {0,10}", (double)(stop - start) / 1000);
- Console.ReadKey();
- }
- }
- }
运行结果:
结果一般在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文件的更多相关文章
- $ npm install opencv ? 你试试?! 在windows环境下,使用node.js调用opencv攻略
博主之前写过一篇文章<html5与EmguCV前后端实现——人脸识别篇>,叙述的是opencv和C#的故事.最近在公司服务器上更新了一套nodejs环境,早就听闻npm上有opencv模块 ...
- vs2010下C++调用lib或dll文件
注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1 设置工程的 ...
- win10环境下使用苹果虚拟机不要开多线程应用下载文件
win10环境下使用苹果虚拟机开多线程应用下载文件时候卡死,网络老掉. 8GB内存不够用?2.5mb网速不够用? 开的百度网盘下载个电影 结果虚拟机卡的不行 关了 网盘 挂起虚拟机 然后再 继续运行客 ...
- Centos7环境下使用Nginx托管.Net Core应用程序
一.安装.Net Core 参考官方文档:https://www.microsoft.com/net/core#linuxcentos 1.添加dotnet产品Feed 在安装.NET Core之前, ...
- LNMP环境下独立安装Mysql5.7.18 并对数据库文件进行本地物理迁移 (需暂停数据库服务方式)
前几天读研时候的同学要我帮忙给解决一个问题,就是Redhat服务器下面安装了LNMP,并且由于分区的划分不当导致MySQL数据库中存放数据库的盘区内空间被急剧消耗,由于该应用主要是数据分析及备份所用, ...
- ffi模块——node调用动态链接库(.so/.dll文件)
参考资料1:[https://www.npmjs.com/package/ffi] 参考资料2:[http://imweb.io/topic/57732fbef0a5487b05f325bf] 参考资 ...
- iOS 在 ARC 环境下 dealloc 的使用、理解误区
iOS 在 ARC 环境下 dealloc 的使用.理解误区 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致&qu ...
- Linux环境下编译并执行ava helloworld程序
原文:http://blog.lupaworld.com/home-space-uid-24466-do-blog-id-2578.html 已经学会怎样在Windows下怎样编辑,编译和运行Java ...
- nodejs 修改端口号 process.env.PORT(window环境下)
各个环境下,nodejs设置process.env.PORT的值的命令,如下1.linux环境下: PORT= node app.js 使用上面命令每次都需要重新设置,如果想设置一次永久生效,使用下面 ...
随机推荐
- CS229 笔记08
CS229 笔记08 Kernel 回顾之前的优化问题 原始问题为: \[ \min_{w,b} \frac{1}{2}||w||^2\\[1.5em] {\text{s.t.}}y^{(i)}\le ...
- 克隆虚拟机重启之后eth0不见的解决方案
今天用虚拟机克隆多一个虚拟机的时候,发现克隆之后的新虚拟机的网卡eth0在配置之后完全是用不了的,下面说一下我的解决办法,亲测可用. 1.用ipconfig命令查看ip信息的时候会发现虚拟机没有找到e ...
- 交互题(二分)(D. Game with modulo)
题目链接:http://codeforces.com/contest/1104/problem/D 题目大意:给出一个式子 x%a y%a,会返回结果,如果返回x代表x%a>=y%a.如果返回y ...
- Xgboost理解
一.xgboost模型函数形式 xgboost也是GBDT的一种,只不过GBDT在函数空间进行搜索最优F的时候,采用的是梯度下降法也就是一阶泰勒展开:而xgboost采用的是二阶泰勒展开也就是牛顿法, ...
- 利用shell找出15分钟内修改的文件
如果你的文件只是生成不会修改的话,可以这样: find * -mmin -15 2>/dev/null 如果可能修改,则需要这样(先创建一个 15 分之前的时间戳的文件,然后找比这个文件新的文件 ...
- 环境变量GOPATH使用试验
Intel Core i5-8250U,Windows 10家庭中文版,Visual Studio Code 1.26.1 中午的时候,自己把环境变量GOBIN给清空了.刚刚继续工作时发生了异常:使用 ...
- 【TensorFlow】获取object detection API训练模型的输出坐标
如下图,谷歌开源的object detection API提供了五种网络结构的fine-tuning训练权重,方便我们针对目标检测的需求进行模型训练,本文详细介绍下导出训练模型后,如何获得目标检测框的 ...
- iOS仿安卓手势解锁
界面是一个九宫格的布局.九宫格实现思路. 先确定有多少列 cloum = 3; 计算出每列之间的距离 计算为: CGFloat margin = (当前View的宽度 - 列数 * 按钮的宽度) / ...
- Intellij IDEA15: 带着参数 运行
package main.scala /** * Created by silentwolf on 2016/5/24. */ object FileIO { def main(args: Array ...
- js跨越请求的2中实现 JSONP /后端接口设置运行跨越header
由于浏览器同源策略,a域名的js向b域名ajax请求会被禁止.JS实现跨越访问接口有2中办法. 1.后端接口设置允许跨越的header头. //header('Access-Control-Allow ...