Alex's profileAlex: the Early BirdPhotosBlogListsMore Tools Help

Blog


    在C里面调用Matlab(分享一点心得,并备忘)

    似乎有位朋友很受困扰,就做了玩玩。

    申明:不代表是最好的方案,更不代表没有错误。

    由于强调必须是C而不是C++,我的那套Managed CLR就不算了。.NET提供的功能很受用啊,用.NET这个东西5分钟就搞定。

    Anyway,回到古典C。在MS Visual Studio 2008 Express下调试通过,肯定不是标准C了,个别小差异我就懒得去管了。

    Matlab提供了其他语言程序调用Matlab的功能,称为Matlab Extern,具体可见Matlab下Extern文件夹,里面甚至都有C的例子。

    例子里都有源代码,我也把我的贴在最后,就不多废话了。有兴趣的读者自己看吧。

    主要提一下,除了源代码,链接时需要添加libmat.lib, libmx.lib,libmex.lib等库(看用到哪些功能加哪些库,这些库都在Matlab\Extern\Lib下面,具体根据平台选择)。在Visual Studio里面可以添加在project里面,gcc的话应该是gcc ... lib libeng.lib ...不记得了,错了表骂我。

    玩了半个小时弄的源代码(英文弱,大家可以无视注释语句),很久不写C了:

    // Matlab4C.cpp

    #include <iostream>
    #include <cmath>
    #include <cstdlib>
    // Matlab Engine. If you want to save the labor of inputing full directory,
    just add this direction to include for the project
    #include "D:\\Matlab\\extern\\include\\engine.h"   

    // Three libraries needed for this project
    #pragma comment( lib, "D:\\Matlab\\extern\\lib\\win32\\microsoft\\msvc70\\libeng.lib" )
    #pragma comment( lib, "D:\\Matlab\\extern\\lib\\win32\\microsoft\\msvc70\\libmex.lib" )
    #pragma comment( lib, "D:\\Matlab\\extern\\lib\\win32\\microsoft\\msvc70\\libmx.lib" )

    // Just found that this is a feature not in C, but C++.
    //It doesn't matter for a C compiler, just delete this line and select proper header files
    using namespace std;

    // Well, again, in C, use main()
    int _tmain(int argc, _TCHAR* argv[])
    {
        // Matlab computing engine
        Engine * pMatlab_Engine;

        // You can add an exception handle(for C++) or an error check if the Matlab is available for calculation
        // btw, my guess is that engOpen is a COM-interop as CreateInstance, so, with a server address, we can
        // actually run Matlab engine on server. This is tentative, no test.
        pMatlab_Engine = engOpen(NULL);

        // Two matrices to play with: parInput is input; parAnswer is the calculation
        mxArray *parInput, *parAnswer;

        // Totally non-sense-made input array
        double pInputData[9] = {4.5,-5,-1,
            5.0,7.3,2.3,
            0.0,2.5,-4.4};

        // Convert our lovely array into matrix
        // Attention! C uses the row-first rule while Matlab seems to have column-first
        // Be very careful that the input might become its transpose in Matlab!!!
        parInput = mxCreateDoubleMatrix(3,3, mxREAL);

        // Oh... the nortorious memcpy ...
        // Anyway, this is a very convenient way to set up the data we want ...
        // No guarantee that this line will not destroy your memory system ...
        memcpy((char *) mxGetPr(parInput), (char *)pInputData, 9*sizeof(double));

        // Let's do something like in Matlab
        engPutVariable(pMatlab_Engine, "data", parInput);

        engEvalString(pMatlab_Engine,"ans = det(data);");

        // Of course, we can use functions in C environment instead of passing these COMMANDS into Matlab
        // There are quite a few function as mlfMTimes to use in C
        // Ref to Matlab External manual

        // Actually the result is a real number, not a matrx
        // but we don't know, or the compiler doesn't know beforehand
        parAnswer = engGetVariable(pMatlab_Engine,"ans");

        // Passing the output back to C
        // We know it's a real number, so a double pointer suffices
        double *pOutput;

        pOutput = mxGetPr(parAnswer);

        // Output stuff
        fgetc(stdin);

        printf("%d",*pOutput);

        // Close and return the resource.
        // What if you don't have this line? you might not be able to use Matlab engine untill restart
        engClose(pMatlab_Engine);

        return 0;
    }

    最后结语:Matlab跟其他编程语言的合作方式很多,两个方向都可以。此外,工业级的工程应该要做成DLL互相调用。不管了都是,后话。

    ref:

    http://www.codeproject.com/KB/cpp/matlab_c_api.aspx

    http://www.mathworks.com.au/access/helpdesk/help/pdf_doc/matlab/apiext.pdf

    http://wibirama.com/dip/wp-content/uploads/2008/11/matlab-api-to-c.ppt

    Comments (3)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    BB Cwrote:
    恩,我试试VS,一直都用VIM+GCC,VS有点生疏了。
    7 Dec.
    Alex Ywrote:
    在VS里面建的,文件名就cpp了,哈;
    在extern下面有这些文件夹;
    _TCHAR基本就是wchar,VS里面包装了几乎所有基本类型。
    7 Dec.
    BB Cwrote:
    开头写的是Matlab4C.cpp,我的MATLAB没有GCC的文件夹Microsoft下也没有msvc70文件夹。版本R2008a。G++报错说'_TCHAR' not declared。
    7 Dec.

    Trackbacks

    The trackback URL for this entry is:
    http://alexorge.spaces.live.com/blog/cns!73DD4A9E3C71BEA6!1902.trak
    Weblogs that reference this entry
    • None