【问题标题】:Create a python COM object创建一个 python COM 对象
【发布时间】:2018-10-23 13:16:50
【问题描述】:

我想知道是否有某种方法可以将 python 脚本封装为 COM 对象。

我看到许多主题都在谈论从 python 调用 COM 组件,但我对相反的感兴趣:创建一个实际上是 python 的 COM 组件。

我有一些用 python 制作的库,我想从 excel 电子表格中调用它们,我认为这可能是一个很好的方法。

【问题讨论】:

  • 不幸的是,如果没有库的帮助,构建 COM 对象并不容易。有不同的 Python 库有助于使用外部 COM 对象,但我知道没有一个能够轻松构建可调用的 COM 对象。所以我担心当前的问题对于这个网站来说太宽泛了。我的建议是使用 ATL 在 C++ 中创建这样一个对象并让它调用 Python 代码,但是示例代码对于 SO 答案来说太大了。
  • 也许这会有所帮助:github.com/mhammond/pywin32。有一个示例似乎创建了一个 COM 对象:github.com/mhammond/pywin32/blob/master/com/win32com/servers/…

标签: c# python windows com pywin32


【解决方案1】:

这样做的一种方法可能是使用 .NET 创建一个 COM 对象并使用 IronPython 执行 Python 代码。

以下是它如何工作的想法:

using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using IronPython.Hosting;

namespace PythonComObject
{
    [Guid("F34B2821-14FB-1345-356D-DD1456789BBF")]
    public interface PythonComInterface
    {
        [DispId(1)]
        bool RunSomePython();
        [DispId(2)]
        bool RunPythonScript();
    }

    // Events interface 
    [Guid("414d59b28-c6b6-4e65-b213-b3e6982e698f"), 
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface PythonComEvents 
    {
    }

    [Guid("25a337e0-161c-437d-a441-8af096add44f"),
    ClassInterface(ClassInterfaceType.None),
    ComSourceInterfaces(typeof(PythonComEvents))]
    public class PythonCom : PythonComInterface
    {
        private ScriptEngine _engine;

        public PythonCom()
        {
            // Initialize IronPython engine
            _engine = Python.CreateEngine();
        }

        public bool RunSomePython()
        {
            string someScript = @"def return_message(some_parameter):
                                      return True";
            ScriptSource source = _engine.CreateScriptSourceFromString(someScript, SourceCodeKind.Statements);

            ScriptScope scope = _engine.CreateScope();
            source.Execute(scope);
            Func<int, bool> ReturnMessage = scope.GetVariable<Func<int, bool>>("return_Message");

            return ReturnMessage(0);
        }


        public bool RunPythonScript()
        {
            ScriptSource source = _engine.CreateScriptSourceFromFile("SomeScript.py");
            ScriptScope scope = _engine.CreateScope();
            source.Execute(scope);               
            Func<int, bool> some_method = scope.GetVariable<Func<int, bool>>("some_method");
            return some_method(1);
        }
    }
}

我还没有尝试过,这只是一个想法,我希望它有效,或者至少让你朝着正确的方向前进。

一些有用的参考资料:

https://blogs.msdn.microsoft.com/seshadripv/2008/06/30/how-to-invoke-a-ironpython-function-from-c-using-the-dlr-hosting-api/

http://ironpython.net

https://www.nuget.org/packages/IronPython/

【讨论】:

  • 谢谢,我会仔细看看。
猜你喜欢
  • 2011-09-10
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2011-09-08
  • 2018-03-13
相关资源
最近更新 更多