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

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


1.建立tteHwif.dll项目
在WPF(C#)工程中使用C导出动态库DLL_第1张图片
项目创建完成
在WPF(C#)工程中使用C导出动态库DLL_第2张图片
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
在WPF(C#)工程中使用C导出动态库DLL_第3张图片

LIBRARY "tteHwif"

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

5.解决方案配置选择”release”,在解决方案上右键,选择”重新生成解决方案”,生成tteHwif.dll,在release文件夹下
在WPF(C#)工程中使用C导出动态库DLL_第4张图片
二.使用tteHwif.dll


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

三.BUG


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

在WPF(C#)工程中使用C导出动态库DLL_第10张图片

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

你可能感兴趣的:(WPF)