在WPF(C#)工程中使用C导出动态库DLL

会有一股神秘感。 提交于 2019-12-09 02:52:43

运行环境:Visual Studio 2017
一.创建动态库


1.建立tteHwif.dll项目
这里写图片描述
项目创建完成
这里写图片描述
2.tteHwif.cpp

// DLLshow.cpp: 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "tteHwif.h"


//启动自检
bool _stdcall tteStartSelfCheck()
{
    if (rd() > 5)
        return true;
    else
        return false;
}
//获取自检状态
bool _stdcall tteGetSelfCheckStatus(bool* status)
{

    if (rd() > 2)
    {
        if (rd() > 2)
            *status = true;
        else
            *status = false;
        return true;
    }
    else
        return false;
}
//获取同步信息
bool _stdcall tteGetSyncStatus(bool* syncStatus, bool* lanAStatus, bool* lanBStatus, unsigned int* timeOffset)
{
    *syncStatus = IsSync();
    *lanAStatus = IsPortAWork();
    *lanBStatus = IsPortBWork();
    *timeOffset = GetSynOffset();
    if (rd() > 2)
        return true;
    else
        return false;
}
//获取速率和抖动
bool _stdcall tteGetRateJitter(int type, int index, unsigned int* rate, unsigned int* jitter)
{
    if (index == 1)
    {
        *rate = GetRate();
        *jitter = GetSynOffset();
    }
    else if (index == 2)
    {
        *rate = 0;
        *jitter = 0;
    }
    else
    {
        *rate = 10;
        *jitter = 10;
    }

    if (type == 0 || type == 1)
    {
        if (index == 1 || index == 2 || index == 3)
        {
            return true;
        }
        else
        {
            return true;
        }
    }
    else if (type == 2)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//端口A状态
 bool _stdcall IsPortAWork()
{
    if (rd()> 5)
        return true;
    else
        return false;
}
//端口B状态
 bool _stdcall IsPortBWork()
{
    if (rd() > 5)
        return true;
    else
        return false;
}
//同步状态
 bool _stdcall IsSync()
{
    if (rd() > 5)
        return true;
    else
        return false;
}
//同步偏差
 unsigned int _stdcall GetSynOffset()
{
     return rd();
}

//产生1-10的随机数
 unsigned int _stdcall rd()
 {
     srand((unsigned)time(NULL));
     return rand() % 10 + 1;
 }

 //实时速率
 unsigned int _stdcall GetRate()
 {
     return rd();
 }

3.在”头文件”下添加tteHwif.h

#pragma once
extern "C" _declspec(dllexport) bool _stdcall tteGetSyncStatus(bool* syncStatus, bool* lanAStatus, bool* lanBStatus, unsigned int* timeOffset);
extern "C" _declspec(dllexport) bool _stdcall tteStartSelfCheck();
extern "C" _declspec(dllexport) bool _stdcall tteGetSelfCheckStatus(bool* status);
extern "C" _declspec(dllexport) bool _stdcall tteGetRateJitter(int type, int index, unsigned int* rate, unsigned int* jitter);
//以下只是工具函数,不是接口函数,但是也要写出来
extern "C" _declspec(dllexport) unsigned int _stdcall rd();
extern "C" _declspec(dllexport) bool _stdcall IsPortAWork();
extern "C" _declspec(dllexport) bool _stdcall IsPortBWork();
extern "C" _declspec(dllexport) bool _stdcall IsSync();
extern "C" _declspec(dllexport) unsigned int _stdcall GetRate();
extern "C" _declspec(dllexport) unsigned int _stdcall GetSynOffset();

4.在”源文件”下添加deffile.def
这里写图片描述

LIBRARY "tteHwif"

EXPORTS
tteGetSyncStatus @ 1
tteStartSelfCheck @ 2
tteGetSelfCheckStatus @ 3
tteGetRateJitter @ 4

5.解决方案配置选择”release”,在解决方案上右键,选择”重新生成解决方案”,生成tteHwif.dll,在release文件夹下
这里写图片描述
二.使用tteHwif.dll


1.将tteHwif.dll复制到WPF工程文件->bin->Debug目录下
这里写图片描述
2.需要添加一个using来支持动态库,使用接口函数前需要先声明
这里写图片描述
这里写图片描述
3.在函数中使用接口函数(在类前添加了unsafe,此处就可以省略unsafe块)
这里写图片描述
注:想使用unsafe块,需勾选“允许不安全代码”
这里写图片描述

三.BUG


1.在项目中添加引用失败

这里写图片描述

解决:需要引用Dll文件中的接口函数非.NET的dll,需要DllImport。C#添加引用需要这个dll本身是.net的程序集,或者是一个COM组件。如果是一个标准的C导出Dll,那么需要用DllImport导入函数,根本不需要在解决方案下面添加引用,只要将dll文件放到指定地方即可
这里写图片描述
解决方案配置为Debug,dll文件放入对应的Debug文件夹中,此时又分为any CPU,x86,x64,不同平台有各自的Debug文件夹,如上图所示
解决方案配置为Release,dll文件放入对应的Release文件夹中,此时又分为any CPU,x86,x64,不同平台有各自的Release文件夹。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!