如何将Matlab7.0函数转换成VC++6.0动态链接库

    技术2022-05-20  36

    1 、 mcc4.0 编译环境设置在桌面上右键单击“我的电脑”图标出现以下菜单

     

    单击“属性”菜单项,出现“系统特性”对话框,单击“高级”选项卡,如下图所示

     

    在上图中,单击“环境变量”按钮,出现“环境变量”对话框, 添加系统变量 matlab 值为 C:/MATLAB7 即 matlab7.0 的安装路径,如下图所示

     

    在环境变量 path 中加入 C:/MATLAB7/bin/win32 ,如下图所示

     

    按“确定”完成设置后, 重启计算机或注销当前用户 ,即可应用新设置。

    2 、 Matlab7.0 编译器设置(1) mex 命令设置

    (a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mex -setup ”命令后,按回车键,安装 Matlab 编译器;

    (b) 命令窗口出现如下提示:

    Please choose your compiler for building external interface (MEX) files:

    Would you like mex to locate installed compilers [y]/n?

    此时键入 ”y” ,按回车;

    (c) 命令窗口出现如下提示:

    Please choose your compiler for building external interface (MEX) files:

    Would you like mex to locate installed compilers [y]/n? y

    Select a compiler:

    [1] Digital Visual Fortran version 6.0 in C:/Program Files/Microsoft Visual Studio

    [2] Lcc C version 2.4 in C:/MATLAB6P5/sys/lcc

    [3] Microsoft Visual C/C++ version 6.0 in C:/Program Files/Microsoft Visual Studio

    [0] None

    此时键入 ” 3” ,按回车 ;选择 Microsoft Visual C++6.0 的编译器

    (d) 命令窗口出现如下提示:

    Please verify your choices:

    Compiler: Microsoft Visual C/C++ 6.0

    Location: C:/Program Files/Microsoft Visual Studio

    Are these correct?([y]/n):

    此时键入 ”y” ,按回车 ;确认选择 Microsoft Visual C++6.0 的编译器

    (2) mbuild 命令设置

    (a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mbuild -setup ”命令后,按回车键,安装 Matlab 编译器;

    (b) 命令窗口出现如下提示:

    Please choose your compiler for building standalone MATLAB applications:

    Would you like mbuild to locate installed compilers [y]/n?

    此时键入 ”y” ,按回车 ;

    (c) 命令窗口出现如下提示:

    [1] Lcc C version 2.4 in C:/MATLAB6P5/sys/lcc

    [2] Microsoft Visual C/C++ version 6.0 in C:/Program Files/Microsoft Visual Studio

    [0] None

    此时键入 ” 2” ,按回车 ;选择 Microsoft Visual C++6.0 的编译器

    (d) 命令窗口出现如下提示:

    Please verify your choices:

    Compiler: Microsoft Visual C/C++ 6.0

    Location: C:/Program Files/Microsoft Visual Studio

    Are these correct?([y]/n):

    此时键入 ”y” ,按回车 ,确认选择 Microsoft Visual C++6.0 的编译器,编译器设置完成。

    3 、编写 Matlab 函数函数文件 sum_prod.m ,内容如下:

    function [sum,prod] = sum_prod(p1,p2)

    sum = p1+p2; % p1 与 p2 的和

    prod = p1.*p2; % p1 与 p2 的点乘

    该函数完成的是矩阵的求和与点乘的功能,下面将介绍把该代码转换成 VC++ 环境可用的代码的方法。

    4 、将 Matlab 函数转成 DLL 函数在 Matlab7.0 的 Command Window 下输入命令 :

    命令 1 : mcc -W lib:libsum_prod -T link:lib sum_prod.m

    命令 2 : mcc -W cpplib:libsum_prod -T link:lib sum_prod.m

    生成动态链接库 DLL ,编译完成后, Matlab 生成一些文件, 其中

    libsum_prod.ctf

    libsum_prod.dll

    libsum_prod.h

    libsum_prod.lib

    这些文件是我们后面需要用到的。

    特别注意 : 命令 1 生成的 DLL 函数接口的数据类型是 mxArray ,命令 2 生成的 DLL 函数接口的数据类型是 mwArray 。

    5 、 VC++6.0 工程的创建与设置(1) 建立一个名为 Test 的 C++ 控制台工程,在工程中添加一个名为 Test.cpp 文件

    (2) 对 VC ++ 6.0 ,进行以下设置

    单击菜单 Tools ,出现如下菜单

     

    单击 Options… 菜单项,出现 Options 对话框,选择 Directories 标签,在 include files 里面加入:

    C:/MATLAB7/EXTERN/INCLUDE

    如下图所示

     

    在 Library files 里面加入:

    C:/MATLAB7/EXTERN/LIB/WIN32/MICROSOFT/MSVC60

    如下图所示

     

    (3) 对该工程,进行以下设置

    单击菜单 Project ,出现如下菜单

     

    单击 Setting… 菜单项,出现 Project Setting 对话框,选择 Link 标签,在 Object/library modules: 下面的文本框内容的后面加入 mclmcrrt.lib libsum_prod.lib ,如下图所示

     

    6 、代码编辑及 DLL 调用(1) 将前面生成的四个文件:

    libsum_prod.ctf

    libsum_prod.dll

    libsum_prod.h

    libsum_prod.lib

    复制到 VC 工程所在目录。

    (2) 在 VC ++ 6.0 环境中, 单击菜单 Project , 选择 Add to Project 菜单项,再单击 Files… 子菜单项,出现如下图对话框,

     

    将 libsum_prod.h 加入到当前工程中。

    (3) 当用命令 1 生成的 DLL 函数时 ,在工程文件 Test.cpp 中添加以下代码:

    #include "iostream.h" // 输入输出头文件

    #include "mclmcr.h" // mxArray 类型声明

    #include "libsum_prod.h" // DLL 头文件

    void display(const mxArray* in, const char* name);

    int main()

    {

    // 初始化程序

    if( ! mclInitializeApplication(NULL,0) )

    {

    fprintf(stderr, "Could not initialize the application./n");

    exit(1);

    }

    // 初始化库

    if (! libsum_prodInitialize() )

    {

    fprintf(stderr,"Could not initialize the library./n");

    exit(1);

    }

    // 声明 DLL 函数输入输出 mxArray 对象

    mxArray *X,*Y;

    mxArray *SUM=NULL,*PROD=NULL;

    // 给输入 mxArray 对象分配内存

    X = mxCreateDoubleMatrix(2,3,mxREAL);

    Y = mxCreateDoubleMatrix(2,3,mxREAL);

    double x[] = {1,2,3,4,5,6};

    double y[] = {7,8,9,10,11,12};

    // 给输入 mxArray 对象赋值

    memcpy(mxGetPr(X),x,6*sizeof(double));

    memcpy(mxGetPr(Y),y,6*sizeof(double));

    // 调用 DLL 函数,注意输入与输出的接口是不同的

    mlfSum_prod(2,&SUM,&PROD,X,Y) ;

    // 显示 mxArray 对象

    display(SUM,"SUM");

    display(PROD,"PROD");

    // 释放输入输出 mxArray 对象所占用的内存

    // 注意输出对象的内存是在调用 DLL 函数过程中分配的

    mxDestroyArray(X);

    mxDestroyArray(Y);

    mxDestroyArray(SUM);

    mxDestroyArray(PROD);

    // 关闭库和程序

    libsum_prodTerminate() ;

    mclTerminateApplication() ;

    return 0;

    }

    // 显示矩阵函数

    void display(const mxArray* in, const char* name)

    {

    int i,j,r,c;

    double *data;

    data = mxGetPr(in);

    r = mxGetM(in);

    c = mxGetN(in);

    printf("%s = /n",name);

    for(i=0;i<r;i++)

    {

    printf("/t");

    for(j=0;j<c;j++)

    printf("% 4.2f /t",data[j*r+i]);

    printf("/n");

    }

    printf("/n");

    }

    该 C++ 程序运算结果如下图所示

     

    (4) 当用命令 2 生成的 DLL 函数时 ,在工程文件 Test.cpp 中添加以下代码:

    #include "iostream.h" // 输入输出头文件

    #include "mclmcr.h" // mwArray 类型声明

    #include "libsum_prod.h" // DLL 头文件

    void display(const double* data, const int r, const int c, const char* name);

    int main()

    {

    // 初始化程序

    if( ! mclInitializeApplication(NULL,0) )

    {

    fprintf(stderr, "Could not initialize the application./n");

    exit(1);

    }

    // 初始化库

    if (! libsum_prodInitialize() )

    {

    fprintf(stderr,"Could not initialize the library./n");

    exit(1);

    }

    // 声明 DLL 函数输入输出 mwArray 对象

    mwArray X(2,3,mxDOUBLE_CLASS);

    mwArray Y(2,3,mxDOUBLE_CLASS);

    mwArray SUM,PROD;

    double x[] = {1,2,3,4,5,6};

    double y[] = {7,8,9,10,11,12};

    double *sum,*prod;

    sum = new double[6];

    prod = new double[6];

    // 给输入 mwArray 对象赋值

    X.SetData(x,6);

    Y.SetData(y,6);

    // 调用 DLL 函数

    sum_prod(2,SUM,PROD,X,Y) ;

    // 取出输出数据

    SUM.GetData(sum,6);

    PROD.GetData(prod,6);

    // 显示 mwArray 对象

    // std::cout << "SUM = " << std::endl << SUM << std::endl;;

    // std::cout << "PROD = " << std::endl << PROD << std::endl;;

    display(sum,2,3,"SUM");

    display(prod,2,3,"PROD");

    delete sum;

    delete prod;

    // 关闭库和程序

    libsum_prodTerminate() ;

    mclTerminateApplication() ;

    return 0;

    }

    // 显示矩阵函数

    void display(const double* data, const int r, const int c, const char* name)

    {

    int i,j;

    printf("%s = /n",name);

    for(i=0;i<r;i++)

    {

    printf("/t");

    for(j=0;j<c;j++)

    printf("% 4.2f /t",data[j*r+i]);

    printf("/n");

    }

    printf("/n");

    }

    该 C++ 程序运算结果如下图所示

     

    特别说明:

    在 C/C++ 环境中二维数组是“行向量” ,如果将下面定义的变量 x 看成二维数组的话

    double x[] = {1,2,3,4,5,6};

    那么 x 应该是 的矩阵,即

    x = [1,2,3;

    4,5,6];

    但是,如果将数组首地址 x 初始化 mxArray 和 mwArray 类时, 数组 x 在 mxArray 和 mwArray 类中是按“列向量”的形式排列 的,即

    X = [1,3,5;

    2,4,6];

    同理,这里

    Y = [7,9,11;

    8,10,12];

    因此才能得到上图的结果

     

    本文来自博客,转载请标明出处:http://blog.csdn.net/kyszp123/archive/2009/12/18/5030026.aspx


    最新回复(0)