将VC++动态链接库封装成C#可以用的动态链接库步骤
来源:互联网 发布:linux系统简介 编辑:程序博客网 时间:2024/06/05 05:13
- VS2008下,File->new->Progect,Project types选择Visual C++下面的CLR,Templates选择Class Library。键入项目名称PXI3223Base(C#用的动态链接库的名称),选择路径,点击OK完成项目新建。
- 将VC下的PXI3223DeciceDll.h(API头文件), PXI3223DeviceDll.lib(静态库)复制到项目路径下的PXI3223Base文件夹下;同时将PXI3223DeviceDll.dll(C++下动态链接库)复制到C:\WINDOWS\system32下。在VS2008项目名PXI3223Base上右键,菜单Add->Existing Item..选择PXI3223DeciceDll.h,将PXI3223DeciceDll.h添加到项目目录中。
- 编写PXI3223Base.h及PXI3223Base.cpp,语法参考C++/cli标准。
- 编译,在项目路径\Debug下会生成PXI3223Base.dll。将此DLL文件放在C:\WINDOWS\system32下,在C#测试项目中添加引用,即可使用该动态链接库。
- 注意:在c++的API头文件PXI3223DeciceDll.h中,要添加#include “windows.h”。
- 下面为PXI3223DeciceDll.h的代码
#define PXI3223_API __declspec(dllexport)__stdcall#else#define PXI3223_API __stdcall#endif#include "windows.h"#define MaxNum 4struct ADConfigParam{ UINT channelSelect; //通道选择 UINT sampleRate; //采样速率 UINT sampleCount; //采样次数 UINT fifoLevel; //fifo中断级别 UINT range; //量程范围};//通道补偿参数struct CompParam{ BOOL bCompOffset[8]; BOOL bCompGain[8]; float fCompOffset[8]; float fCompGain[8];};typedef enum _RET_STATUS{ RET_SUCCESS = 0, RET_DEVICE_INITIALFAIL = -1, RET_DEVICE_NONEXIST = -2, RET_DEVICE_CLOSEFAIL = -3, RET_EVENT_CREATEFAIL = -4, RET_IRP_SENTFAIL = -5, RET_PARAM_ILLEGAL = -6, RET_UNKOWN_ERROR = -7, RET_Thread_CreateFail = -8, RET_Synchronize_error = -9, RET_Thread_AlreayRuning =-0xa, RET_ALLOCATEMEM_FAIL = -0xB, RET_Thread_NotRunning = -0x0c, RET_EVENT_REGISTER_FAIL = -0x0d, RET_THREAD_SETPRI_FAIL = -0x0e, RET_THREAD_RESUME_FAIL = -0x0f}RETSTATUS,*PRESTATUS;//#ifdef __cplusplus//extern "C" {//#endif//打开板卡。//devNum:设备号,从0开始BOOLEAN PXI3223_API PXI3223_OpenCard(DWORD DevNum);//功能: 关闭板卡//参数: DevNum 板卡号//返回值:true 操作成功// false 操作失败BOOLEAN PXI3223_API PXI3223_Close(DWORD DevNum);//复位,对9054寄存器复位//devNum:设备号,从0开始BOOLEAN PXI3223_API PXI3223_ResetAll(DWORD DevNum);////////////////////////////IO输入输出函数,两个函数不能同时使用,视硬件情况而定/////////////////////////////////////////DevNum:设备号,从0开始// outputData:低七位分别对应七个通道,从低位到高位分别为1-7通道,如outputData=0x03则通道IO0和通道IO1为高BOOLEAN PXI3223_API PXI3223_IOOutput(DWORD DevNum, UINT outputData);//DevNum:设备号,从0开始// *pInputData:低七位分别对应七个通道,从低位到高位分别为1-7通道,如*pInputData=0x03则通道IO0和通道IO1为高BOOLEAN PXI3223_API PXI3223_IOInput(DWORD DevNum, UINT* pInputData);/////////////////////////////AD函数///////////////////////////////////////////////DevNum: 设备号,从0开始//ADConfigParam param:// struct ADConfigParam// {// UINT channelSelect; //通道选择,低八位每一位对应一个通道,选中即为1,未选中为0.如0x0003,则是通道1,通道2被选中// UINT sampleRate; //采样速率,范围为1-20的整数,分别对应1M-20M,sampleRate=1代表采样速率为1M,以此类推// UINT sampleCount; //采样次数。指开启AD采集后,每个选中的通道可采集的数据数量。由于硬件缓存原因,8个通道加在一起最大采样次数为64M。另外采样次数必 //须是偶数。// UINT fifoLevel; //fifo中断级别,即缓存FIFO中触发中断的数据数量界限,最大可设置为(8K - 1),且表示FIFO中双字的数据数量,因为FIFO位宽32位,AD采集 //位宽为14位,故存储时两个AD数据构成32位存储在FIFO中,这也是采样次数必须是偶数的原因。如设置为1,表示缓存FIFO中含有两个AD数据后 //触发中断// UINT range; //量程范围,0代表-1——1量程,1代表-10——10量程// };BOOLEAN PXI3223_API PXI3223_ADConfig(DWORD DevNum, ADConfigParam param, CompParam compParam);//开始接收函数(DMA中断)// devNum:设备号,从0开始// pRecvData: 接收数据的数组指针,数组大小应为recvNum*recvFrame个FLOAT// recvNum : 选中的通道个数,通道2,3,7被选中则为3,范围为1-8// recvFrame: 每个通道读取数据数量。为跟配置信息中的采样次数相匹配,此值必须为偶数,且不能大于配置信息中采样数据数量,否则函数一直处于等待状态RETSTATUS PXI3223_API PXI3223_DmaRecv(DWORD devNum, FLOAT* pRecvData, USHORT recvNum, USHORT recvFrame);//开始采集函数,在PXI3223_ADConfig之后调用,在PXI3223_DmaRecv之前调用,//调用顺序应为PXI3223_ADConfig->PXI3223_ADStart->PXI3223_DmaRecv(or PXI3223_RecvData)//devNum:设备号,从0开始RETSTATUS PXI3223_API PXI3223_ADStart(DWORD DevNum);//AD停止采集;devNum:设备号,从0开始RETSTATUS PXI3223_API PXI3223_ADStop(DWORD DevNum);//#ifdef __cplusplus//}//#endif`
PXI3223Base.h代码
#pragma once#pragma comment(lib, "PXI3223DeviceDLL.lib")#include "PXI3223DeviceDLL.h"using namespace System;namespace PXI3223Base { public ref class PXI3223 { // TODO: Add your methods for this class here. private: DWORD devNum;//设备号 public: bool isOpened;//标志板卡是否打开状态 //构造函数 PXI3223(int _devNum) { devNum = _devNum; isOpened = false; } //打开板卡 //返回值:true表示打开成功,isOpened状态变为true // 若板卡已经打开,也返回true。但会抛出"PXI3223卡已经打开!"异常 bool Open(); //关闭板卡 //返回值:true表示成功关闭。isOpened状态变为false // 若板卡已经关闭,则返回true。但会抛出"PXI3223卡已关闭!"异常 bool Close(); //复位板卡 //返回值:true表示成功复位板卡。 // false表示复位板卡失败或板卡尚未打开(同时抛出"PXI3223卡尚未打开!"异常)。 bool ResetAll(); ////////////////////////////IO输入输出函数,两个函数不能同时使用,视硬件情况而定/////////////////////////////////////// //IO输出 //outputData:低七位分别对应七个通道,从低位到高位分别为1-7通道,如outputData=0x03则通道IO0和通道IO1为高 //返回值:true表示IO输出成功, // false表示IO输出失败或板卡尚未打开(同时抛出"PXI3223卡尚未打开!"异常)。 bool IOOutput(UINT outputData); //IO输入 //返回值:低七位分别对应七个通道,从低位到高位分别为1-7通道,如*pInputData=0x03则通道IO0和通道IO1为高 // 返回0x80表示IO输入失败,或板卡尚未打开(同时抛出"PXI3223卡尚未打开!"异常)。 UINT IOInput(); //AD转换开启 //返回值:开启成功返回枚举型的RET_SUCCESS // 失败返回失败状态码。尚未打开板卡返回RET_DEVICE_INITIALFAIL,同时抛出"PXI3223卡尚未打开!"异常。 bool ADStart(); //AD转换停止 //返回值:成功停止AD返回枚举型的RET_SUCCESS // 失败返回失败状态码。尚未打开板卡返回RET_DEVICE_INITIALFAIL,同时抛出"PXI3223卡尚未打开!"异常。 bool ADStop(); //配置AD //ADConfigParam param:AD配置参数 // struct ADConfigParam // { // UINT channelSelect; //通道选择,低八位每一位对应一个通道,选中即为1,未选中为0.如0x0003,则是通道1,通道2被选中 // UINT sampleRate; //采样速率,范围为1-20的整数,分别对应1M-20M,sampleRate=1代表采样速率为1M,以此类推 // UINT sampleCount; //采样次数。指开启AD采集后,每个选中的通道可采集的数据数量。由于硬件缓存原因,8个通道加在一起最大采样次数为64M。另外采样次数必 //须是偶数。 // UINT fifoLevel; //fifo中断级别,即缓存FIFO中触发中断的数据数量界限,最大可设置为(8K - 1),且表示FIFO中双字的数据数量,因为FIFO位宽32位,AD采集 //位宽为14位,故存储时两个AD数据构成32位存储在FIFO中,这也是采样次数必须是偶数的原因。如设置为1,表示缓存FIFO中含有两个AD数据后 //触发中断 // UINT range; //量程范围,0代表-1——1量程,1代表-10——10量程 // }; //CompParam compParam通道补偿参数 //struct CompParam //{ // BOOL bCompOffset[8]; //是否偏执补偿 // BOOL bCompGain[8]; //是否增益补偿 // float fCompOffset[8]; //偏置补偿参数(输入0V时的差值) // float fCompGain[8]; //增益补偿参数(输入满量程时的实测值) //}; //返回值:true表示成功配置AD // false表示AD配置失败或或板卡尚未打开(同时抛出"PXI3223卡尚未打开!"异常)。 bool ADConfig(UINT channelSelect, UINT sampleRate, UINT sampleFrame, UINT fifoLevel, UINT range, array<BOOL>^ bCompOffset, array<BOOL>^ bCompGain, array<float>^ fCompOffset, array<float>^ fCompGain); //读取AD转换数据 //recvChNum打开的通道个数 //recvFrame每个通道AD转换次数 //返回值:接收成功返回读取的AD浮点值,容量为recvChNum * recvFrame的数组 // 接收失败返回空指针nullptr,若未打开板卡,抛出"PXI3223卡尚未打开!"异常。 array<float>^ DmaRecv(USHORT recvChNum, USHORT recvFrame); };}
PXI3223Base.cpp代码
#include "stdafx.h"#include "PXI3223Base.h"namespace PXI3223Base { bool PXI3223::Open() { if(isOpened) { throw gcnew InvalidOperationException("PXI3223卡已经打开!"); return true; } else { if(!PXI3223_OpenCard(devNum)) { throw gcnew InvalidOperationException("打开PXI3223卡失败!"); return false; } else { isOpened = true; return true; } } } bool PXI3223::Close() { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡已关闭!"); return true; } else { if(!PXI3223_Close(devNum)) { throw gcnew InvalidOperationException("关闭PXI3223卡失败!"); return false; } else { isOpened = false; return true; } } } bool PXI3223::ResetAll() { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return false; } else { if(!PXI3223_ResetAll(devNum)) { throw gcnew InvalidOperationException("整体复位失败!"); return false; } return true; } } ////////////////////////////IO输入输出函数,两个函数不能同时使用,视硬件情况而定/////////////////////////////////////// // outputData:低七位分别对应七个通道,从低位到高位分别为1-7通道,如outputData=0x03则通道IO0和通道IO1为高 bool PXI3223::IOOutput(UINT outputData) { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return false; } else { if(!PXI3223_IOOutput(devNum, outputData)) { throw gcnew InvalidOperationException("PXI3223卡IO输出失败!"); return false; } return true; } } //返回值:低七位分别对应七个通道,从低位到高位分别为1-7通道,如*pInputData=0x03则通道IO0和通道IO1为高 UINT PXI3223::IOInput() { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return 0x80; } else { UINT inputData = 0x80; if(!PXI3223_IOInput(devNum, &inputData)) { throw gcnew InvalidOperationException("PXI3223卡IO输入失败!"); inputData = 0x80; } return inputData; } } //DevNum: 设备号,从0开始 //ADConfigParam param: // struct ADConfigParam // { // UINT channelSelect; //通道选择,低八位每一位对应一个通道,选中即为1,未选中为0.如0x0003,则是通道1,通道2被选中 // UINT sampleRate; //采样速率,范围为1-20的整数,分别对应1M-20M,sampleRate=1代表采样速率为1M,以此类推 // UINT sampleCount; //采样次数。指开启AD采集后,每个选中的通道可采集的数据数量。由于硬件缓存原因,8个通道加在一起最大采样次数为64M。另外采样次数必 //须是偶数。 // UINT fifoLevel; //fifo中断级别,即缓存FIFO中触发中断的数据数量界限,最大可设置为(8K - 1),且表示FIFO中双字的数据数量,因为FIFO位宽32位,AD采集 //位宽为14位,故存储时两个AD数据构成32位存储在FIFO中,这也是采样次数必须是偶数的原因。如设置为1,表示缓存FIFO中含有两个AD数据后 //触发中断 // UINT range; //量程范围,0代表-1——1量程,1代表-10——10量程 // }; bool PXI3223::ADConfig(UINT channelSelect, UINT sampleRate, UINT sampleFrame, UINT fifoLevel, UINT range, array<BOOL>^ bCompOffset, array<BOOL>^ bCompGain, array<float>^ fCompOffset, array<float>^ fCompGain) { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return false; } else { ADConfigParam configParam; configParam.channelSelect = channelSelect; configParam.sampleRate = sampleRate; configParam.sampleCount = sampleFrame; configParam.fifoLevel = fifoLevel; configParam.range = range; CompParam compParam; for(int i = 0; i < 8; i++ ) { compParam.bCompOffset[i] = bCompOffset[i]; compParam.bCompGain[i] = bCompGain[i]; compParam.fCompOffset[i] = fCompOffset[i]; compParam.fCompGain[i] = fCompGain[i]; } if(!PXI3223_ADConfig(devNum, configParam, compParam)) { throw gcnew InvalidOperationException("PXI3223卡AD配置失败!"); return false; } return true; } } array<float>^ PXI3223::DmaRecv(USHORT recvChNum, USHORT recvFrame) { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return nullptr; } else { array<float>^ pRecvData = gcnew array<float>(recvChNum * recvFrame); pin_ptr<float> pADBuf = &pRecvData[0]; RETSTATUS retStatus = PXI3223_DmaRecv(devNum, pADBuf, recvChNum, recvFrame); if(retStatus != RET_SUCCESS) { throw gcnew InvalidOperationException("PXI3223卡读取AD数据失败!"); return nullptr; } return pRecvData; } } bool PXI3223::ADStart() { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return false; } else { RETSTATUS retStatus = PXI3223_ADStart(devNum); if(retStatus != RET_SUCCESS) { throw gcnew InvalidOperationException("开启AD转换失败!"); return false; } return true; } } bool PXI3223::ADStop() { if(!isOpened) { throw gcnew InvalidOperationException("PXI3223卡尚未打开!"); return false; } else { RETSTATUS retStatus = PXI3223_ADStop(devNum); if(retStatus != RET_SUCCESS) { throw gcnew InvalidOperationException("开启AD转换失败!"); return false; } return true; } }}
0 0
- 将VC++动态链接库封装成C#可以用的动态链接库步骤
- 用VC++封装自己的DLL动态链接库
- VC中加载外部动态链接库的步骤:
- vc中添加动态链接库dll的步骤
- c# 封装动态链接库dll
- VC++动态链接库
- VC++ 动态链接库
- VC++动态链接库
- 用dll动态链接库将函数封装
- c#与vc调用动态链接库
- c#中如何调用vc++写的动态链接库
- C# 动态链接库
- 创建动态链接库的步骤
- 创建动态链接库的步骤
- codeblocks加入动态链接库的步骤。
- 动态链接库创建步骤
- VC++动态链接库的加载方法
- VC++动态链接库(DLL)的加载
- iOS本地推送(本地通知)
- hexo 安装
- Python yield 使用浅析
- ionic 中的 $scope.$watch 问题
- 读取properties简单Demo_me
- 将VC++动态链接库封装成C#可以用的动态链接库步骤
- 人脸性别识别文献阅读笔记(1)
- 算法设计方法
- virtual Box 运行 Ubuntu 常见问题
- 《编译.java文件时的编码问题》更新版本
- Android 4.4 自动拨打分机流程分析
- 数据结构实验之求二叉树后序遍历和层次遍历
- creationComple
- 图的遍历之 深度优先搜索和广度优先搜索