C# 用参数在C代码中调用matlab方法
我试图在我的C代码中用参数调用matlab方法。我使用反射在运行时将带有matlab函数的dll加载到我的应用程序中,效果很好:C# 用参数在C代码中调用matlab方法,c#,matlab,reflection,invoke,method-parameters,C#,Matlab,Reflection,Invoke,Method Parameters,我试图在我的C代码中用参数调用matlab方法。我使用反射在运行时将带有matlab函数的dll加载到我的应用程序中,效果很好: Assembly matlabAssembly = Assembly.LoadFrom(info.FullName); List<Type> types = new List<Type>(); types = matlabAssembly.GetTypes().ToList(); List<MethodInfo> method
Assembly matlabAssembly = Assembly.LoadFrom(info.FullName);
List<Type> types = new List<Type>();
types = matlabAssembly.GetTypes().ToList();
List<MethodInfo> methods = new List<MethodInfo>();
methods.AddRange(types[0].GetMethods());
dynamic dynamicObject = Activator.CreateInstance(types[0]);
我创建了一些数组,并希望将它们作为参数传递给这个函数。为了使MWARRY类型在编译时可供C使用,我将Matlab运行时中的Assembly MWARRY.dll静态地添加到我的项目中
MWArray array1 = new MWNumericArray(120);
MWArray array2 = new MWNumericArray(100);
MWArray array3 = new MWNumericArray(15);
MWArray array4 = new MWLogicalArray(true);
object[] params = new object[] {array1, array2, array3, array4};
MethodInfo matlabFuncion = methods[5]; //MyMatlabFunction
matlabFunction.Invoke(dynamicObject, params);
调用invoke方法时,我得到一个异常,即MWNummericArray无法转换为MWArray,尽管MWNummericArray直接从MWArray派生。我是遗漏了什么还是完全错了?如果有人偶然发现同样的问题,我找到了以下解决方案: 当您希望在C应用程序中运行Matlab代码时,需要从Matlab运行时中引用MWArray.dll。但是,如果将对此dll的引用以静态方式添加到项目中,它将无法工作,因为引用无法加载 解决方案是使用反射加载对MWArray的引用,并为MWArray动态创建实例
public void Foo()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
// Load dll which was exported from Matlab into application
string path = @"..\..\..\..\MatlabDlls\Matlab-Integration";
string dllName = "MyExportedMatlabDLL.dll";
List<string> dllPaths = Directory.GetFiles(path).Where(file => file.EndsWith(dllName)).ToList();
FileInfo info = new FileInfo(dllPaths[0]);
Assembly matlabAssembly = Assembly.LoadFrom(info.FullName);
// Get types from exported dll
List<Type> exportedMatlabTypes = new List<Type>();
exportedMatlabTypes = matlabAssembly.GetTypes().ToList();
List<MethodInfo> methods = new List<MethodInfo>();
methods.AddRange(exportedMatlabTypes[0].GetMethods());
// Create instance of exported Matlabtype
dynamic dynamicObject = Activator.CreateInstance(exportedMatlabTypes[0]);
// Select MWArray from loaded Assemblies
// Important: MWArray could only be loaded into the application with
// the ResolveEventHandler further below
Assembly mwArrayAssembly = AppDomain.CurrentDomain.GetAssemblies().Where(name => name.FullName.Contains("MWArray")).ToList()[0];
// Get all available types of MWArray
List<Type> MWArrayTypes = mwArrayAssembly.GetTypes().ToList();
// Create some MWArrays
// MWNummericArray
dynamic array1 = Activator.CreateInstance(MWArrayTypes[9], new object[] { new byte[640 * 480]});
//MWNummericArray
dynamic array2 = Activator.CreateInstance(MWArrayTypes[9], new object[] { 100 });
//MWLogicalArray
dynamic array3 = Activator.CreateInstance(MWArrayTypes[5], new object[] { true });
// Parameters for Matlab function
object[] params= new object[] { array1, array2, array3};
MethodInfo matlabFuncion = methods[5];
var result = matlabFuncion.Invoke(dynamicObject, params);
}
// The ResolveEventHandler ensures the proper loading of dependent assemblies
// I wrote a crawler that would search inside the Matlab runtime for dependent
// assemblies. It is enough to just load "MWArray" from a static path...
private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
Assembly dependentAssembly = null;
string assemblyName = args.Name.Split(',')[0];
string assemblypath = _crawler.getFullName(_runtimepath, assemblyName);
if (assemblypath != string.Empty)
dependentAssembly = Assembly.LoadFile(assemblypath);
return dependentAssembly;
}
public void Foo()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
// Load dll which was exported from Matlab into application
string path = @"..\..\..\..\MatlabDlls\Matlab-Integration";
string dllName = "MyExportedMatlabDLL.dll";
List<string> dllPaths = Directory.GetFiles(path).Where(file => file.EndsWith(dllName)).ToList();
FileInfo info = new FileInfo(dllPaths[0]);
Assembly matlabAssembly = Assembly.LoadFrom(info.FullName);
// Get types from exported dll
List<Type> exportedMatlabTypes = new List<Type>();
exportedMatlabTypes = matlabAssembly.GetTypes().ToList();
List<MethodInfo> methods = new List<MethodInfo>();
methods.AddRange(exportedMatlabTypes[0].GetMethods());
// Create instance of exported Matlabtype
dynamic dynamicObject = Activator.CreateInstance(exportedMatlabTypes[0]);
// Select MWArray from loaded Assemblies
// Important: MWArray could only be loaded into the application with
// the ResolveEventHandler further below
Assembly mwArrayAssembly = AppDomain.CurrentDomain.GetAssemblies().Where(name => name.FullName.Contains("MWArray")).ToList()[0];
// Get all available types of MWArray
List<Type> MWArrayTypes = mwArrayAssembly.GetTypes().ToList();
// Create some MWArrays
// MWNummericArray
dynamic array1 = Activator.CreateInstance(MWArrayTypes[9], new object[] { new byte[640 * 480]});
//MWNummericArray
dynamic array2 = Activator.CreateInstance(MWArrayTypes[9], new object[] { 100 });
//MWLogicalArray
dynamic array3 = Activator.CreateInstance(MWArrayTypes[5], new object[] { true });
// Parameters for Matlab function
object[] params= new object[] { array1, array2, array3};
MethodInfo matlabFuncion = methods[5];
var result = matlabFuncion.Invoke(dynamicObject, params);
}
// The ResolveEventHandler ensures the proper loading of dependent assemblies
// I wrote a crawler that would search inside the Matlab runtime for dependent
// assemblies. It is enough to just load "MWArray" from a static path...
private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
Assembly dependentAssembly = null;
string assemblyName = args.Name.Split(',')[0];
string assemblypath = _crawler.getFullName(_runtimepath, assemblyName);
if (assemblypath != string.Empty)
dependentAssembly = Assembly.LoadFile(assemblypath);
return dependentAssembly;
}