在64位机器上编译32位Matlab应用程序(c ++)

7
我目前正在64位机器上使用64位MatLab,用C++构建32位MatLab引擎应用程序。然而,我已经拥有了所有32位MatLab引擎的dll和库文件。这些库文件和dll被正确加载(我可以编译并启动应用程序,没有任何错误),但32位dll似乎启动了64位MatLab可执行文件,因此当我尝试与引擎交互时,程序会崩溃。有没有办法让我的应用程序启动32位MatLab可执行文件而不是64位的呢?
提前感谢!
1个回答

9
可以实现,但非常混乱:在我看来,整个mbuild/deploytool系统都是一坨屎。deploytool.bat的第一个问题是,虽然有“-win32”选项,但当deploytool不从32位安装目录调用时,该选项根本没有任何效果。第二个问题是,mbuild选项适用于32位和64位版本,因此必须手动指定,否则将使用错误的编译器选项。
以下是我在安装了VS2010的64位Windows机器上编译32位和64位的一些操作:
- 必须安装32位和64位Matlab版本 - 必须通过命令行完成所有操作 - 您永远不能通过deploytool UI编辑您的.prj文件,因为它会破坏所有手动更改。 (好吧,实际上这是一个好处,因为现在至少您将能够将它们存储在VCS中) - 通过在“configuration”部分下添加到prj中指向正确的编译器选项(见下文)来查找正确的编译器选项 - 通过手动提供32位安装的deploytool.bat的完整路径来构建 prj中的选项文件配置:
<deployment-project>
  <configuration ....>
    ....
    <param.c.cpp.options.file>${MATLAB_ROOT}\bin\win32\mbuildopts\msvc100compp.bat</param.c.cpp.options.file>
    ....

请注意,32位和64位版本的输出目录等内容将相同。实际上,如果您需要为多个项目执行此操作,这将变得完全不可管理。因此,我有一个 msbuild 脚本,可以让生活变得更加轻松:基本上,在 prj 文件中,我使用宏替换了所有平台相关的内容(输出目录、matlab 根目录、选项文件位置),然后让 msbuild 复制 prj 并使用正则表达式查找/替换宏与依赖于平台的值。这样可以在两个平台上使用相同的 prj。
更新
经过对我们项目的一些重大更改后,我们发现处理 matlab prj 文件的麻烦不值得。 相反,我们通过直接调用 mcc 并向其提供属于项目的所有文件来大大简化了一切。以下是相关的 msbuild 代码;某些错误检查被省略以保持清晰性:
<Target Name="BuildMatlabProject">
  <PropertyGroup Condition="$(MlPlatform)=='x86'">
    <MlMatlabBinDir>$(MlMatlabx86Dir)\bin\win32</MlMatlabBinDir>
  </PropertyGroup>
  <PropertyGroup Condition="$(MlPlatform)=='x64'">
    <MlMatlabBinDir>$(MlMatlabx64Dir)\bin\win64</MlMatlabBinDir>
  </PropertyGroup>
  <ItemGroup>
    <MlMFiles Include="$(MlMatlabProjDir)\*.m"/>
    <MlMResources Include="$([System.IO.Directory]::GetDirectories(&quot;$(MlMatlabSrcDir)&quot;))"/>
  </ItemGroup>
  <PropertyGroup>
    <MlMresourcseString Condition="@(MlMResources)!=''"> -a @(MlMResources, ' -a ')</MlMresourcseString>
  </PropertyGroup>
  <RemoveDir Directories="$(MlOutDir)" ContinueOnError="true"/>
  <MakeDir Directories="$(MlOutDir)"/>
  <Exec Command="$(MlMatlabBinDir)\mcc -W cpplib:$(MlOutputName)_$(MlPlatform)
 -T link:lib -d $(MlOutDir) -f $(MlMatlabBinDir)\mbuildopts\msvc100compp.bat
 -w enable:specified_file_mismatch -w enable:repeated_file -w enable:switch_ignored
 -w enable:missing_lib_sentinel -w enable:demo_license -v
 @(MlMFiles, ' ') $(MlMresourcseString)"/>
</Target>

这需要以下属性:

  • MlPlatform: x86用于构建32位,x64用于构建64位
  • MlMatlabx86Dir: matlab 32位安装目录的路径
  • MlMatlabx64Dir: matlab 64位安装目录的路径
  • MlMatlabProjDir: 包含要编译的m文件的“工程”目录的路径
  • MlMatlabSrcDir: 具有额外源m文件的路径
  • MlOutDir: 输出目录
  • MlOutputName: 输出名称

1
哇...谢谢你的回答。我想我只是要卸载MatLab 64位并安装32位。我不需要导出到64位,我只是希望有一种简单的方法可以编译为32位而不必安装32位MatLab。顺便说一下,我根本没有手动使用deploytool。我只是让vs2010为我编译所有东西。 - Tiddo
1
我仔细阅读了您的回答,但我仍然不明白为什么我的程序无法工作:我没有使用Matlab中的任何构建工具,我只是包含和链接库和dll文件,以便我的程序可以使用引擎。据我所知,deploytool只是一个工具,用于使用MEX文件的正确设置编译程序。然而,我不会构建MEX文件,并且手动配置我需要的设置。但是,有没有办法以某种方式设置设置,以便我可以导出到32位而无需安装32位版本呢? - Tiddo
1
@Tiddo你用什么库?在我的64位安装中,extern/lib/win64下只有64位的库,所以它们不可能用于构建32位版本。 - stijn
1
不,但是在我的大学里有一些安装了32位系统的电脑(这就是为什么需要构建32位),所以我从那里复制了它。没有这些库,程序根本无法编译。使用64位DLL可以编译,但程序将无法启动引擎。使用32位dll和lib会启动,但正如我在第一篇帖子中所说,只要我对它做任何操作,它就会失败。 - Tiddo
1
在这种情况下,您确定运行时使用的所有DLL都在您的路径中吗?不仅仅是mclmcrt,而且在bin/win32目录下有大约50个DLL,几乎所有这些DLL都是32位的,并且运行时引擎会使用其中的绝大部分。 - stijn
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接