gpt4 book ai didi

c# - 很好地处理缺少对 COM 接口(interface) (MATLAB) 的引用

转载 作者:太空宇宙 更新时间:2023-11-03 15:37:03 26 4
gpt4 key购买 nike

我有一个引用 MATLAB COM 接口(interface)的 VS2013 C# 项目。该应用程序 90% 的功能与 MATLAB 无关,我希望能够在 MATLAB 不可用的环境中编译和运行。期望的行为是:

  • 构建,不管引用是否存在(抛出警告)。
  • 如果 MATLAB 不可用,则在用户尝试执行 MATLAB 特定功能时打印一条消息,但这不应是致命的。

我的第一直觉是使用具有不同构建配置的预处理器指令,但我想避免这种情况,因为在设置持续集成和测试等时它会变得困惑。

所以我尝试了一些反射(reflection):

try
{
var matlab = Activator.CreateComInstanceFrom("appname.exe", "MLApp.MLApp").Unwrap();
}
catch
{
//message
}

抛出 MissingMethodException(即找不到构造函数)。当 MATLAB 存在时,这工作正常:

     var matlab = new MLApp.MLApp();

欢迎提出新想法,提前致谢!

编辑:请参阅下面的详细答案,但对于那些正在寻找快速测试代码的人来说,这里是对我有用的。

        var Matlab_t = Type.GetTypeFromProgID("Matlab.Autoserver");

if (Matlab_t != null)
matlab = Activator.CreateInstance(Matlab_t);
else
MessageBox.Show("Matlab installation not found.\n");

最佳答案

在我的 COM 相关单元测试/检测器中,我只是分多个步骤进行:

  1. 查找 COM 类型
  2. 根据类型创建 COM 对象
  3. 调用方法。
  4. 释放所有 COM 对象。

在你的情况下,我建议编写映射器类,将所有这些 COM 丑陋之处隐藏在抽象层下。 (我只是需要那些助手来测试我写的COM库,所以它是相反的)

Type.GetTypeFromProgID当找不到类型时不抛出异常,而是简单地返回 null

    public static object GetComObject(string typeName)
{
Type ComType;

ComType = Type.GetTypeFromProgID(typeName);
if (ComType == null)
{
//COM type not found
}
// Create an instance of your COM Registered Object.
return Activator.CreateInstance(ComType);
}

当创建(或不创建)对象时,我会跟进 dynamic 或手写反射(做与 dynamic 相同的事情,但控制程度更高,并且也适用于旧的 .NET 版本).

    public static object CallFunction(string method, string typeName, params object[] args)
{
Type ComType;
object ComObject;

ComType = Type.GetTypeFromProgID(typeName);
if (ComType == null)
{
//COM type not found
}

// Create an instance of your COM Registered Object.
ComObject = Activator.CreateInstance(ComType);

// Call the Method and cast return to whatever it should be.
return ComType.InvokeMember(method, BindingFlags.InvokeMethod, null, ComObject, args);
}

工作完成后,您应该释放它们,全部释放。包括由根 COM 对象中的方法(创建)返回的对象。 (释放父项,但不释放其子项,除了 memleaks 之外,还会导致单元测试引擎卡住,令人讨厌)

    public static void DisposeCOM(dynamic obj)
{
if (obj != null)
{
Marshal.ReleaseComObject(obj);
}
}

关于c# - 很好地处理缺少对 COM 接口(interface) (MATLAB) 的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31537049/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com