将VC++动态链接库封装成C#可以用的动态链接库步骤

来源:互联网 发布:linux系统简介 编辑:程序博客网 时间:2024/06/05 05:13
  1. VS2008下,File->new->Progect,Project types选择Visual C++下面的CLR,Templates选择Class Library。键入项目名称PXI3223Base(C#用的动态链接库的名称),选择路径,点击OK完成项目新建。
  2. 将VC下的PXI3223DeciceDll.h(API头文件), PXI3223DeviceDll.lib(静态库)复制到项目路径下的PXI3223Base文件夹下;同时将PXI3223DeviceDll.dll(C++下动态链接库)复制到C:\WINDOWS\system32下。在VS2008项目名PXI3223Base上右键,菜单Add->Existing Item..选择PXI3223DeciceDll.h,将PXI3223DeciceDll.h添加到项目目录中。
  3. 编写PXI3223Base.h及PXI3223Base.cpp,语法参考C++/cli标准。
  4. 编译,在项目路径\Debug下会生成PXI3223Base.dll。将此DLL文件放在C:\WINDOWS\system32下,在C#测试项目中添加引用,即可使用该动态链接库。
  5. 注意:在c++的API头文件PXI3223DeciceDll.h中,要添加#include “windows.h”。
  6. 下面为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