从 C# 调用 mexCallMATLAB
Call mexCallMATLAB from C#
我正在尝试使用 Pinvoke 从 C# 调用 Matlab 函数。
我的项目配置是:
- 使用"mex.h"调用"mexCallMATLAB"接口的C++项目
示例:
#include "stdafx.h"
#include <stdarg.h>
#include <string>
#include "matrix.h"
#include "mex.h"
extern "C" _declspec(dllexport) bool blockExists()
{
std::string blockPath = "model/myblockpath";
mxArray *pin[1];
int nin = 1;
mxArray *pout[1];
int nout = 1;
pin[0] = mxCreateString( blockPath.c_str() );
if ( mexCallMATLAB( nout, pout, nin, pin, "find_system" ) != 0 ) {
callStatus = false;
}
mxDestroyArray( pin[0] );
return callStatus;
}
- 使用 PInvoke 调用以前的 c++ 项目的 C# 项目
示例:
using System.Runtime.InteropServices;
namespace ManagedMatlabWrapper
{
public class MatlabWrapper
{
[DllImport(@"MatlabAPI.dll")]
private static extern bool blockExists();
public static bool blockExistsAPI()
{
bool result = blockExists();
return result;
}
}
}
编译一切正常
但是当我 运行 代码时,它给我一个 DLL not found 异常的错误。
我检查了使用 dependency walker 生成的 DLL,它显示找不到某些 Matlab DLL。如果我更改代码并删除对 Matlab 的任何引用,Pinvoke 运行 就好了。
有谁知道少了什么?我应该怎么做才能从 C# 调用 mexCallMATLAB?
该错误告诉您并非所有依赖项都可以找到。您的描述表明您的 C++ DLL 位于。但它又至少依赖于 libmex
、libmx
和 msvcr90
。无法解决部分或所有这些依赖项。
解决该问题的一种廉价(且肮脏)的方法是将包含 MATLAB 库的目录添加到 PATH
。更好的方法是在导致 MATLAB 的第一个 p/invoke 调用之前,通过调用 SetDllDirectory
或 AddDllDirectory
来修改 DLL 搜索路径。
MSVCR90
的问题可以通过为该版本的 MSVC 安装 MSVC 可再发行组件包来解决。
最后,MATLAB 通过 .net 程序集公开了它的功能。为什么不使用这些来避免所有这些复杂性。
mexCallMATLAB 将无法工作,除非通过 MEX 文件从 MATLAB 进程调用它。没有它,就会有太多未初始化的上下文。因此,即使您在搜索路径上找到了正确的 DLL,当您尝试执行它时它也会崩溃。
听起来您最好还是看看 MATLAB Engine API or the MATLAB COM Automation Server。
我正在尝试使用 Pinvoke 从 C# 调用 Matlab 函数。
我的项目配置是:
- 使用"mex.h"调用"mexCallMATLAB"接口的C++项目
示例:
#include "stdafx.h"
#include <stdarg.h>
#include <string>
#include "matrix.h"
#include "mex.h"
extern "C" _declspec(dllexport) bool blockExists()
{
std::string blockPath = "model/myblockpath";
mxArray *pin[1];
int nin = 1;
mxArray *pout[1];
int nout = 1;
pin[0] = mxCreateString( blockPath.c_str() );
if ( mexCallMATLAB( nout, pout, nin, pin, "find_system" ) != 0 ) {
callStatus = false;
}
mxDestroyArray( pin[0] );
return callStatus;
}
- 使用 PInvoke 调用以前的 c++ 项目的 C# 项目
示例:
using System.Runtime.InteropServices;
namespace ManagedMatlabWrapper
{
public class MatlabWrapper
{
[DllImport(@"MatlabAPI.dll")]
private static extern bool blockExists();
public static bool blockExistsAPI()
{
bool result = blockExists();
return result;
}
}
}
编译一切正常
但是当我 运行 代码时,它给我一个 DLL not found 异常的错误。
我检查了使用 dependency walker 生成的 DLL,它显示找不到某些 Matlab DLL。如果我更改代码并删除对 Matlab 的任何引用,Pinvoke 运行 就好了。
有谁知道少了什么?我应该怎么做才能从 C# 调用 mexCallMATLAB?
该错误告诉您并非所有依赖项都可以找到。您的描述表明您的 C++ DLL 位于。但它又至少依赖于 libmex
、libmx
和 msvcr90
。无法解决部分或所有这些依赖项。
解决该问题的一种廉价(且肮脏)的方法是将包含 MATLAB 库的目录添加到 PATH
。更好的方法是在导致 MATLAB 的第一个 p/invoke 调用之前,通过调用 SetDllDirectory
或 AddDllDirectory
来修改 DLL 搜索路径。
MSVCR90
的问题可以通过为该版本的 MSVC 安装 MSVC 可再发行组件包来解决。
最后,MATLAB 通过 .net 程序集公开了它的功能。为什么不使用这些来避免所有这些复杂性。
mexCallMATLAB 将无法工作,除非通过 MEX 文件从 MATLAB 进程调用它。没有它,就会有太多未初始化的上下文。因此,即使您在搜索路径上找到了正确的 DLL,当您尝试执行它时它也会崩溃。
听起来您最好还是看看 MATLAB Engine API or the MATLAB COM Automation Server。