首页 > 其他 > 详细

VS中 DLL的创建及函数导出(参考MSDN)

时间:2015-12-31 14:30:40      阅读:272      评论:0      收藏:0      [点我收藏+]

新建一个DLL工程

  新建 - 项目 - vc++ - win32 - win32控制台应用程序,工程名假设取为 MathFuncsDll

  技术分享

向导中选择DLL,取消预编译头

技术分享

完成。

此时会有dllmain.cpp, MathFuncsDll.cpp 两个cpp文件及生成的 stdafx.h, targetver.h stdafx.cpp, 后面这三个文件其实是没用的,可以删掉,然后把dllmain.cpp 中的#include "stdafx.h"改成#include <windows.h>

给工程添加一个头文件MathFuncsDll.h用来定义我们的函数,现在的工程文件如图:技术分享

 

在DLL中函数导出有两种方式,一种是利用__declspec(dllexport)语句声明函数,这样便不需要def文件即可导出函数,比如

extern "C" __declspec(dllexport) double  Add1(double a, double b);

对应的函数定义

__declspec(dllexport) double Add1(double a, double b) {
        return a + b;
    }

这里extern "C" 是为了在DLL中生成的函数名不会变化,如果不用该句,Add1在DLL中的导出函数里可能是叫做Add1@SANNN@之类之类的,不方便动态调用(LoadLibrary,GetProcAddress)。

通过denpency walker可以看DLL的导出函数及其名称,这里显示的名称就是GetProcAddress()函数需要的名称,如果名称不对将获取不了函数

  技术分享

另一种方法是利用def文件,这种方法得到的导出函数名称更好看,适合动态调用。此时函数的定义就可以写的比较简单了

double Divide2(double a, double b);

double Divide2(double a, double b) {
    if (b == 0)
        throw invalid_argument("b cannot be zero!");
    return a / b;
}

在工程中插入def文件,按下面代码编写

LIBRARY    MathFuncsDll
EXPORTS
    Divide2 @1

第一行是LIBRARY关键字,后接库名称

第二行是EXPORTS关键字

再往下就是要导出的函数名及其序号。

 

附上代码:

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

#include "MathFuncsDll.h"
#include <stdexcept>

using namespace std;

namespace MathFuncs {
    double MyMathFuncs::Add(double a, double b) {
        return a + b;
    }
    
    double MyMathFuncs::Subtract(double a, double b) {
        return a - b;
    }
    
    double MyMathFuncs::Multiply(double a, double b) {
        return a * b;
    }
    
    double MyMathFuncs::Divide(double a, double b) {
        if (b == 0)
            throw invalid_argument("b cannot be zero!");
        return a / b;
    }
}
MATHFUNCSDLL_API double Add1(double a, double b) {
        return a + b;
    }

MATHFUNCSDLL_API double Subtract1(double a, double b) {
        return a - b;
    }

MATHFUNCSDLL_API double Multiply1(double a, double b) {
        return a * b;
    }

MATHFUNCSDLL_API double Divide1(double a, double b) {
        if (b == 0)
            throw invalid_argument("b cannot be zero!");
        return a / b;
}

double Divide2(double a, double b) {
    if (b == 0)
        throw invalid_argument("b cannot be zero!");
    return a / b;
}

头文件:

#pragma once

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport)
#else
#define MATHFUNCSDLL_API __declspec(dllimport)
#endif

namespace MathFuncs {
    class MyMathFuncs {
    public:
        static MATHFUNCSDLL_API double Add(double a, double b);
        static MATHFUNCSDLL_API double Subtract(double a, double b);
        static MATHFUNCSDLL_API double Multiply(double a, double b);
        static MATHFUNCSDLL_API double Divide(double a, double b);

    };
}
extern "C" MATHFUNCSDLL_API double  Add1(double a, double b);
extern "C" MATHFUNCSDLL_API double Subtract1(double a, double b);
extern "C" MATHFUNCSDLL_API double Multiply1(double a, double b);
extern "C" MATHFUNCSDLL_API double Divide1(double a, double b);
double Divide2(double a, double b);

这里除了普通的函数,还有在命名空间中的类的静态函数。不过这种函数通过GetProcAddress()将会很难调用,如果是通过链接lib文件来调用则会比较容易,比如

cout << "a + b = " <<
        MathFuncs::MyMathFuncs::Add(a, b) << endl;

 

VS中 DLL的创建及函数导出(参考MSDN)

原文:http://www.cnblogs.com/yyisgod/p/5091603.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!