找回密码
 注册
Simdroid-非首页
查看: 261|回复: 9

[讨论]vb与matlab混编的一点体会与困惑

[复制链接]
发表于 2007-8-8 12:30:08 | 显示全部楼层 |阅读模式 来自 四川成都
最近几天一直在做vb与matlab混编的东西,原因是以前用matlab写的优化计算代码,现在老板要求有一个用户界面,并脱离matlab运行。matlab本身也可以做GUI,坛子里面也讨论得 比较多,但我以前却未用过,时间比较紧张,没有办法,只好选用我最熟悉的vb来做了(惭愧的很,不会C++,坛子里面很多都是讨论C++的)。现在已经将此问题基本解决了,下面将我这段时间的一点体会与遇到的问题和大家分享讨论一下:
(先说明一下,所有的代码在matlab下都是没有任何问题的,下面遇到的一些问题是在编译和vb下调用中遇到的)
1、本次编译采用的是matlab7.4版本,即2007a版。
       代码本身是在6.5版下写的,在前期编译中遇到了不少的问题和困难(以前未编译过),后来换到7.0,然后又改到7.4,发现7.4最好用,也最容易找到问题所在。在编译调用中程序如果出错,在其它版本中并不提供错误代码的位置,只给出一个错误对话框,没有具体的信息,而在7.4版中却能明确地给你指出哪一行m代码出了问题(在vb下调用时),这一点是其它版本所不能比的,对于调试来说也是非常好的。

2、vb调用matlab编译的组件格式问题
      这个问题坛子里面已经讨论过,但发现仍然有不少人搞不清楚,其实这个格式非常简单,
            call myDLLName(n,OutVar1,OutVar2,InVar1,InVar2,...)      (抱歉,原来没有写清楚,现在更改一下
     其中n是输出变量的数目,如果是一个变量,就取1,依此类推。OutVar1,OutVar2是输出变量(或返回参数值),在vb下通常声明为Variant类型,InVar1,InVar2是输入变量,它们都是有几个就写几个,其类型可根据matlab中相应参数进行定义,也可定义为Variant类型。

3、编译组件(DLL)
      要实现dll编译,在机子里面需要安装一个C++的编译器,我装的vc++6,编译前需要运行mbuider -setup来选择好你的编译器。在7.4版中编译组件时不再使用comtool了,而是采用的deploytool,使用上非常方便。编译前需要建立一个prj工程文件,在里面输入必需的信息,并在选择对应的编译工具。对于vb6调用的通用DLL com组件,需要选择MATLAB Builder for .NET,再选择Generic COM Component就可以了,若选择.NET Component,编译后的dll在vb6下将无法调用。
      在这次编译中遇到了一个非常奇怪的问题,我的程序在matlab下编译完全没有问题,在vb下调用始终出错,结果发现是m代码中有一个变量我定义了,但我后面又没有使用,后来将这行注释掉后,在vb下居然就正常了。查了帮助也没有发现个所以然。
4、绘图的问题
      在我的m文件中使用了plot来绘制寻优的过程,图形绘制好了以后,使用了text函数在图上面显示优化的结果信息,代码为:
                         text(text_x,text_y,text_str,'fontsize',20);
       在vb下第一次绘图不会出错(连续绘制几十张图),然后vb程序不关闭,另外计算一次,再来点绘图就会出错,调试错误代码就是上面这一行,始终找不到原因,后来将这行注释掉以后,问题消失了。但为了显示这个信息在图片上,我又不得不另外想办法把信息传到vb下,用vb代码来实现该信息的显示。
此错误信息为:


      在此之前还遇到另外一个问题,就是使用figure(i),i是循环变量,使用这种方式来产生图形窗口,结果编译后每次一运行到这一句也老报错,找不到原因,后来把这行给注释掉以后问题居然也解决了。由于figure后面还有axis函数,图形窗口依然能够正常创建。但如何方便地隐掉figure窗口,不让它弹出来还是没有解决好。

5、打包与安装程序制作的问题
     deploytool本身提供了打包的功能,它将你产生的DLL文件和MATLAB运行库文件以及注册工具等一起打包为一个文件myDLLName_pkg.exe,这个文件在运行时还要先解压出MCRInstaller(100多M)、MCRRegCOMComponent.exe和dll文件与_install.bat等文件,解开后自动运行_install.bat文件进行安装注册。由于我使用了Install VISE来制作最后的安装程序,而deploytool提供的这个安装包使用起来并不方便:一方面解压出这些文件需要浪费不少时间,另一方面,这些文件解开后,卸载整个程序时这些文件在安装目录下并不能自动删除。因此我将这个包解开的所有文件直接添加到Install VISE制作的安装程序setup中。
      添加后又出现了一个问题,虽然Install VISE允许在安装过程中执行外部程序,但只限制于exe文件,对于bat文件并不支持。没有办法,只好在vb下又写了一个程序,利用shell命令来实现bat文件的调用,编译后一个exe文件,让Install VISE来执行这个exe文件。编译、打包后一测试,发现shell命令调用bat时使用的cmd窗口,而在vb下,这个窗口并不具有wait功能,也就是说,bat文件的上一个命令还没有执行完,下一行的命令就已经开始执行了,这会导致另外一个问题。mcrinstaller运行时间比较长,而后面的MCRRegCOMComponent.exe myDLLName.dll 将会很快执行,而此时这些文件甚至都还没有解出来,结果就会出错,组件不能正常注册,程序也将无法运行。没有办法,只好在vb再写了一段代码使得cmd窗口具有wait功能,编译,打包后测试终于通过,到别的机子测试也通过。至此,基本内容终于完成。

下面是这个bat文件中的内容:
echo off
echo Deploying project optTS, version 2.0.
IF EXIST MCRInstaller.exe (
echo Running MCRInstaller
MCRInstaller.exe
)
echo Registering the component...
IF EXIST MCRRegCOMComponent.exe (
MCRRegCOMComponent.exe myDLLName.dll
) ELSE (
regsvr32 myDLLName.dll
)
echo Installation complete.
echo Please refer to the documentation for any additional setup steps.

---------------------
感觉:接口编程真花时间。

[ 本帖最后由 urright 于 2007-8-10 17:19 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

1

查看全部评分

发表于 2007-8-10 13:07:11 | 显示全部楼层 来自 北京
Simdroid开发平台
不知道你在编程的时候碰到这个问题没有,我的m文件里面没有绘图的命令,但是我在vb下调用的时候出现了这样的错误:
Invaild root property:"CurrentFigure"
回复 不支持

使用道具 举报

发表于 2007-8-10 15:37:37 | 显示全部楼层 来自 湖北武汉
这个为什么要如此产生figure
h_figure = figure('name','se');
如此方式列?
就是使用figure(i),i是循环变量,使用这种方式来产生图形窗口,结果编译后每次一运行到这一句也老报错,找不到原因,后来把这行给注释掉以后问题居然也解决了
回复 不支持

使用道具 举报

发表于 2007-8-10 15:53:07 | 显示全部楼层 来自 新加坡
写的不错,看起来都是自己的实践经验。谢谢!

不过我不懂VB,看完楼主的帖子后,有一些疑问,希望能给以解答。

原帖由 urright 于 2007-8-8 12:30 发表
...
2、vb调用matlab编译的组件格式问题
      这个问题坛子里面已经讨论过,但发现仍然有不少人搞不清楚,其实这个格式非常简单,
            call myDLLName(n,OutVar,InVar1,InVar2,...)
    其中n是输出变量的数目,如果是一个变量,就取1,依此类推。OutVar是输出变量(或返回参数值),在vb下通常声明为Variant类型,InVar1,InVar2是输入变量,有几个就写几个,其类型可根据matlab中相应参数进行定义,也可定义为Variant类型。...


请问在有多个输出变量(比如两个或者更多)时,那个myDLLName函数中仍然只是一个OutVar吗?我以前也是这样认为的,不过最近我自己测试后发现,m方程有几个输出变量,那里就响应的有几个变量。比如我们用下面这个例子为例:
  1. function [y,z] = myadd2(a, b)
  2. % dummy function, just to demonstrate the idea
  3. y = a+b;
  4. z = a+2*b;
  5. end
复制代码


在matlab中创建一个project,编译生成COM组件,观看产生的代码,我们将发现,所产生的COM组件所导出的函数接口定义为:
  1. Imyadd2class : IDispatch
  2. {
  3.     //
  4.     // Raw methods provided by interface
  5.     //

  6.       virtual HRESULT __stdcall get_MWFlags (
  7.         /*[out,retval]*/ struct IMWFlags * * ppvFlags ) = 0;
  8.       virtual HRESULT __stdcall put_MWFlags (
  9.         /*[in]*/ struct IMWFlags * ppvFlags ) = 0;
  10.       [color=red]virtual HRESULT __stdcall myadd2 (
  11.         /*[in]*/ long nargout,
  12.         /*[in,out]*/ VARIANT * y,
  13.         /*[in,out]*/ VARIANT * z,
  14.         /*[in]*/ VARIANT a,
  15.         /*[in]*/ VARIANT b ) = 0;[/color]
  16.       virtual HRESULT __stdcall MCRWaitForFigures ( ) = 0;
  17. };
复制代码

原帖由 urright 于 2007-8-8 12:30 发表
...
4、绘图的问题
      在我的m文件中使用了plot来绘制寻优的过程,图形绘制好了以后,使用了text函数在图上面显示优化的结果信息,代码为:
                         text(text_x,text_y,text_str,'fontsize',20);
       在vb下第一次绘图不会出错(连续绘制几十张图),然后vb程序不关闭,另外计算一次,再来点绘图就会出错,调试错误代码就是上面这一行,始终找不到原因,后来将这行注释掉以后,问题消失了。但为了显示这个信息在图片上,我又不得不另外想办法把信息传到vb下,用vb代码来实现该信息的显示。
此错误信息为:
...


感觉很有可能是VB程序的错误,而不是编译后程序的问题。另外关于figure(i)在编译后的问题,需要看程序后才能分析。如果只是希望达到动态隐藏、显示某些figure窗口,应该没有问题。这个我在学习混编时做过。

其实混编并不难,也不烦。看着matlab的在线帮助基本上就能搞定大多数问题。不过,好像现在很少有人会“闲”的没事干去看matlab的在线帮助的(不针对任何人,只是有感而发)

评分

2

查看全部评分

回复 不支持

使用道具 举报

 楼主| 发表于 2007-8-10 17:00:50 | 显示全部楼层 来自 四川成都
先回答下楼上taohe大虾的问题
惭愧,我的原文没有写清楚,实在不好意思
OutVar和InVar是一样的,有几个输出参数在vb下就得写几个输出参数,如有2个输入2个输出的情况,在vb 下调用时应当写为     
   call DLLName(2,OutVar1,OutVar2,InVar1,InVar2),
如你举的例子就可写为:call DllName(2,y,z,a,b)
实际上在vb 中调用时,当你输入 “call DLLName.” ,并选择好你的类属性并输入“(”后,关于这个函数的参数就会自动提示出来了。如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

 楼主| 发表于 2007-8-10 17:15:15 | 显示全部楼层 来自 四川成都
绘图的问题我也没有花太多时间去解决了,时间比较紧张,再加上我的matlab非常菜,属于初级阶段以下,一般我都需要一边看帮助和参考书,一边才能编下去,而且编代码的时候还不是很多,所以采用了没有办法的办法。到现在我也不清楚到底是哪里的问题,也许matlab和vb6的接口问题本身可能就不是很理想,不知道在vb.net下会不会有这样的问题,还没有尝试过。
至于隐藏figure窗口的问题,我都看过你们以前讨论的帖子,应该是没有问题的,但c++我实在是不懂,唉,当初学了几天就丢了,现在想学也来不及了。

出现问题后我把与编译、vb接口等相关的帮助大多数都看了,也没有发现什么,也许我漏掉了什么内容


使用句柄方式产生figure,我也试过,在我的程序中感觉效果都差不多
回复 不支持

使用道具 举报

 楼主| 发表于 2007-8-10 17:17:06 | 显示全部楼层 来自 四川成都
原帖由 wtj8359 于 2007-8-10 13:07 发表
不知道你在编程的时候碰到这个问题没有,我的m文件里面没有绘图的命令,但是我在vb下调用的时候出现了这样的错误:
Invaild root property:"CurrentFigure"


这种问题还真没有遇到过,不过建议你安装7.4,可以方便调试
回复 不支持

使用道具 举报

发表于 2007-8-11 20:51:44 | 显示全部楼层 来自 湖北武汉
没那么复杂的
不需要什么C++
几个WIN32 API而已
VB中一样可以使用API
原帖由 urright 于 2007-8-10 17:15 发表
绘图的问题我也没有花太多时间去解决了,时间比较紧张,再加上我的matlab非常菜,属于初级阶段以下,一般我都需要一边看帮助和参考书,一边才能编下去,而且编代码的时候还不是很多,所以采用了没有办法的办法。 ...

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2010-10-19 20:08:01 | 显示全部楼层 来自 浙江杭州
你好请问一下,如果函数参数中有矩阵数据,那VB下应该怎么设置这个矩阵数据,好像用数组不行的,请教 5# urright
回复 不支持

使用道具 举报

发表于 2010-10-26 21:30:20 | 显示全部楼层 来自 北京
凑个热闹,现在坛里关于混编的讨论不多了啊~~
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Simapps系列直播

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-10-5 13:27 , Processed in 0.063535 second(s), 19 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表