全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2357
推到 Plurk!
推到 Facebook!

C++Builder與Matlab混合編程

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-08-16 16:37:01 IP:61.218.xxx.xxx 未訂閱

C++Builder與Matlab混合編程

「作者不詳」 資料來源:http://www.s8s8.net/ 在C++Builder中調用Matlab工具箱函數,有兩種實現方式。一種是基于Matlab環境支持,通過必要的設置實現,筆者在本刊上曾撰文對這種方式進行了專門的闡述。另一種則是完全脫離Matlab環境,通過動態連接庫方式實現對Matlab工具箱函數的調用,這可以通過一種開發平台Mediva來實現。相對來說,前者的限制因素較多,而后者則較為方便靈活。 一、 Mediva軟件平台 Mediva是Mathtools公司推出的一種Matlab編譯開發軟件平台,提供對Matlab程序文件(M文件)的解釋執行和開發環境支持。該軟件有為Borland C++、Visual Basic和Dephi等編程語言開發的不同版本,目前其版本已經到了4.5版,軟件大小僅6.5M,可以通過訪問其站點www.mathtools.com免費下載試用一個月。 Mediva軟件平台本身的功能相當強大,提供近千個 Matlab的基本功能函數,通過必要的設置,就可以直接實現與C++的混合編程,而不必再依賴Matlab;同時,Mediva還提供編譯轉換功能,能夠將Matlab函數或編寫的Matlab 程序轉換為C++形式的DLL,從而實現脫離Matlab環境對Matlab函數和過程的有效調用,這樣就有可能實現對Matlab強大的工具箱函數的利用。 Mediva的缺點是C++與Matlab混合編寫的應用軟件必須攜帶必要的DLL,從而增大了軟件的體積(約4M),同時也不能對所有的Matlab 函數提供支持,例如採用類庫進行設計的部分函數。但盡管如此,對于控制系統計算機設計、分析的工作來說,Mediva仍不失為一個好的工具。 二、 C++Builder直接調用Matlab函數 本文假設已經安裝了Mediva軟件或已經得到必要的兩個動態連接庫mdv4300.dll和ago4300.dll。 Mediva提供的近千個Matlab基本功能函數,都可以在C++Builder中直接調用。這些函數包括基本的操作、命令、I/O、線性代數、位圖、控制等,基本上可以滿足我們的一般需要。當然其最大的優點就是可以直接在C++ Buider中直接調用而不必考慮安裝龐大的Matlab。 其實現方式和步驟如下: 1. Lib文件的生成 在Dos下用C++Builder中的Implib.exe,通過如下命令生成mdv4300.lib: implib mdv4300.lib mdv4300.dll 將上述兩個DLL文件和此Lib文件拷貝到當前目錄下。 2.實現與Matlab的混合編程 Matlab.h包含了Mediva中所有類型、常量、函數的說明和定義,必須將此頭文件放于程序的第一行。Mediva給出的Matlab函數形式並不特殊,如繪線函數Plot,在Mediva中說明為:Mm DLLI plot(cMm varargin);varargin與Matlab 中的意義是一樣的,與輸入變量的個數相對應。所有可以直接使用的函數都在Matlib.h頭文件中定義,而在mdv4300.dll中實現。 但在C++Builder中使用Mediva提供的Matlab函數的格式,與Matlab編程稍有不同,這主要體現在C++中必須進行必要的說明上。例如我們要用繪線函數Plot來繪制數組x[100]的紅色圖線。在Matlab中調用為Plot(x,‘r');在 C++中調用則為:Plot(CL(x),TM(“r")),其中CL是一個關鍵字,是多變量輸入時所必須使用的,用以指明調用的變量;而TM則指明,這是一個字符。 下面我們給出一個示例程序,其功能是對一個1024 點的輸入數組進行FFT變換,並繪制變換后頻譜實部的火柴桿圖,最后將原數據和變換后的數據寫入數據文件中。
  #include“matlib.h"      //必須包含的頭文件
  #include 
  #pragma hdrstop      #include“TryMatcomU.h"
  #pragma package(smart_init)
  #pragma resource“*.dfm"
   Tform1*form1;
   __fastcall Tform1::Tform1(TComponent* Owner)
       : Tform(Owner)
   {
   }
   void __fastcall Tform1::Button1Click(TObject*Sender)
   {
   int k=0;  
   initM(MATCOM_VERSION);         //必須
進行的初始化
   Mm cur1,cur2;              //定義變量
   cur1=zeros(128);  cur2=zeros(128);  //變量初始化       for  (k=1;k<=128;k++)  
   cur1.r(k)=randM();         //生成一個隨機數列
   figure(1);
   plot(cur1);             //圖形顯示該數列
   
   cur2=fft(cur1,128);   //做128點fft變換
   figure(2);
   //繪制fft變換后實部的火柴桿圖,注意此處多變量輸入的格式
   stem((CL(cur1),real(cur2),TM(“r")));    
       
   fid=fopen(filename,mode,format) opens
   exitM();                   //退出調用
   }
如果完全使用C++來實現本程序的工作,其代碼將超過300行!由此可以看出,C++Builder與Matlab函數的混合編程可以給我們帶來多麼大的方便! 3.變量內部狀態/數據的觀察方法 Mediva使用的所有變量均定義為Mm類型。如果在C ++Builder中觀察Mm類型變量的內部狀態/數據,要稍麻煩一些,但在調試程序時,這又是不可避免的一步,這里舉例給出變量觀察的方法。 例如對上面生成的cur2數列進行觀察: *cur2.pr 0.1892 cur2(1)的實部 *cur2.pi 0.0013 cur2(1)的虛部 三、 C++Builder調用Matlab工具箱函數轉換后的DLL 1. Matlab函數向DLL的轉化 Mediva軟件提供了將Matlab函數轉換為DLL的功能,非常方便。但需要注意的是: Matlab5.0以上版本,所有帶有tf類的函數均無法轉換; Matlab4.2以下版本,多數函數能夠轉換,但轉換后大多不能直接使用,而必須加以處理。 MATCOM V4.3中把含有輸入參數的M文件轉換成 DLL時,生成的DLL無法調用。以.M為例: function [x1,x2]=flower(x3) MATCOM生成的FLOWER.CPP和FLOWER.H中聲明為:
    Mm flower(Mm x3, i_o_t, Mm& x1__o, Mm& x2__o) {
   begin_scope
   x3.setname(“x3");
   ...
 }       Mm flower(Mm x3);
   Mm flower(Mm x3, i_o_t, Mm& x1__o, Mm& x2__o);
而生成的G_FLOWER.CPP聲明為:
   void DLLX _stdcall flower_1_1(Mm** in01, Mm**out01)
    void DLLX _stdcall flower_1_2
    (Mm** in01, Mm**out01, Mm**out02)   
其中對于in01的說明是不正確的,應按如下修改,然后,按如下MAKE文件進行編譯。
#
# MATCOM makefile
#    all: flower.dll    g_flower.obj: g_flower.cpp
bcc32-c-Id:\matcom43\-WD-Id:\matcom43\lib
-H=matlib.csm-a4-5-eg_flower.obj g_flower.cpp    flower.dll: flower.obj g_flower.obj
bcc32-Ld:\matcom43\-WD-Id:\matcom43\lib
-H=matlib.csm-a4-5-eflower.dll @flower.rsp
d:\matcom43\lib\mdv4300b.lib
  在CPP中調用這個函數之前,一定要先給in01分配空間。    #include“matlib.h"
#pragma hdrstop
 
#include“flower.h"
 
#define WIN32_LEAN_AND_MEAN    #include 
#include“matlib.h"
#pragma hdrstop
 
 extern“C" {
   void DLLX _stdcall flower_1_1(Mm in01, Mm**out01) {
    *out01=new Mm();
     //*in01=new Mm();
    **out01=flower(in01);
     exitM();
   }
   
void DLLX _stdcall flower_1_2(Mm in01, Mm*
*out01, Mm**out02) {
    *out01=new Mm();*out02=new Mm();
     //*in01=new Mm();      
     flower(in01, i_o ,**out01,**out02);
     exitM();
}      
聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]--- 發表人 - axsoft 於 2002/08/16 16:45:49
系統時間:2024-04-20 13:45:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!