Insert Python interpreter in (Windows) C ++ - application

I am creating a windowed application written in C ++. I would like to use several python libraries.

I don't need some fancy Python here. My method is as follows:

  • Open the thread to start the Python interpreter.

  • Send commands from C ++ to the Python interpreter. C ++ may need to write some intermediate files for interaction.

This method is dirty, but it will work for many interpretative environments, for example. gnuplot, lua.

My question is which API can I use for this task. Maybe I need some kind of Win32 API?

EDIT: I don't need any Python. I really need a general method. So my application can also work with gnuplot, etc.

+3
source share
4 answers

If you have the original Python distribution, you can look in the Demo/embedsample directory . Relevant documentation here .

+4
source

ActivePython (http://www.activestate.com/activepython/downloads) installs itself as an ActiveScript engine. ProgID is Python.AXScript.2. Thus, you can use it with COM through the standard IActiveScript Windows interface. Read on it.

Distribution is another matter. Either you need clients to have it, or you can try and extract juicy bits from the ActiveState package, or maybe the official way to do automatic tuning ...

+2
source

" " IActiveScript ++ ATL, :

  • CSimpleScriptSite
  • IActiveScriptSite IActiveScriptSiteWindow
  • CoCreateInstance Python IActiveSite
  • Python print 'Hello World. 5 squared is: ' + str(5 * 5)
  • Python. MSDN IActiveScriptError
  • stub return S_OK;
  • Python 2.6, Python.
  • Python Windows, ProgID Python, Python IActiveScript wrappers
  • Python, IActiveScript, ProgID (, Python.AXScript.2)

Python Hello World:

#include <atlbase.h>
#include <activscp.h>

#define CHECKHR(stmt) \
    { \
        HRESULT hr = S_OK; \
        if (FAILED(hr = (stmt))) { return hr; } \
    }

class CSimpleScriptSite :
    public IActiveScriptSite,
    public IActiveScriptSiteWindow
{
public:
    CSimpleScriptSite() : m_cRefCount(1), m_hWnd(NULL) { ZeroMemory(&m_clsidScriptEngine, sizeof(m_clsidScriptEngine)); }

    // IUnknown

    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)();
    STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);

    // IActiveScriptSite

    STDMETHOD(GetLCID)(LCID *plcid){ *plcid = 0; return S_OK; }
    STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti) { return TYPE_E_ELEMENTNOTFOUND; } 
    STDMETHOD(GetDocVersionString)(BSTR *pbstrVersion) { *pbstrVersion = SysAllocString(L"1.0"); return S_OK; }
    STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) { return S_OK; }
    STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState) { return S_OK; }
    STDMETHOD(OnScriptError)(IActiveScriptError *pIActiveScriptError) { return S_OK; }
    STDMETHOD(OnEnterScript)(void) { return S_OK; }
    STDMETHOD(OnLeaveScript)(void) { return S_OK; }

    // IActiveScriptSiteWindow

    STDMETHOD(GetWindow)(HWND *phWnd) { *phWnd = m_hWnd; return S_OK; }
    STDMETHOD(EnableModeless)(BOOL fEnable) { return S_OK; }

    // Miscellaneous

    HRESULT CloseScriptEngine();
    HRESULT Evaluate(LPCOLESTR szScript, VARIANT *pResult, LPCOLESTR strItemName);
    HRESULT Execute(LPCOLESTR szScript, LPCOLESTR strItemName);
    HRESULT OpenScriptEngine(CLSID &rclsid);
    HRESULT OpenScriptEngine(LPCOLESTR szScriptEngine);
    HRESULT SetWindow(HWND hWnd) { m_hWnd = hWnd; }

private:
    CComPtr<IActiveScript> m_ptrIActiveScript;
    CLSID                  m_clsidScriptEngine;
    ULONG                  m_cRefCount;
    HWND                   m_hWnd;
};

STDMETHODIMP_(ULONG) CSimpleScriptSite::AddRef()
{
    return InterlockedIncrement(&m_cRefCount);
}

STDMETHODIMP_(ULONG) CSimpleScriptSite::Release()
{
    if (!InterlockedDecrement(&m_cRefCount))
    {
        delete this;
        return 0;
    }
    return m_cRefCount;
}

STDMETHODIMP CSimpleScriptSite::QueryInterface(REFIID riid, void **ppvObject)
{
    if (riid == IID_IUnknown || riid == IID_IActiveScriptSiteWindow)
    {
        *ppvObject = (IActiveScriptSiteWindow *) this;
        AddRef();
        return NOERROR;
    }
    if (riid == IID_IActiveScriptSite)
    {
        *ppvObject = (IActiveScriptSite *) this;
        AddRef();
        return NOERROR;
    }
    return E_NOINTERFACE;
}

HRESULT CSimpleScriptSite::OpenScriptEngine(CLSID &rclsid)
{
    m_ptrIActiveScript = NULL;
    CHECKHR(CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void **) &m_ptrIActiveScript));
    CHECKHR(m_ptrIActiveScript->SetScriptSite(this));
    CComPtr<IActiveScriptParse> ptrIActiveScriptParse;
    CHECKHR(m_ptrIActiveScript->QueryInterface(IID_IActiveScriptParse, (void **) &ptrIActiveScriptParse));
    CHECKHR(ptrIActiveScriptParse->InitNew());
    m_clsidScriptEngine = rclsid;
    return S_OK;
}

HRESULT CSimpleScriptSite::OpenScriptEngine(LPCOLESTR szScriptEngine)
{
    CLSID clsid;
    CHECKHR(CLSIDFromProgID(szScriptEngine, &clsid));
    return OpenScriptEngine(clsid);
}

HRESULT CSimpleScriptSite::CloseScriptEngine()
{
    if (!m_ptrIActiveScript) { return S_OK; }
    CHECKHR(m_ptrIActiveScript->SetScriptState(SCRIPTSTATE_CLOSED));
    m_ptrIActiveScript = NULL;
    return S_OK;
}

HRESULT CSimpleScriptSite::Evaluate(LPCOLESTR szScript, VARIANT *pResult, LPCOLESTR strItemName)
{
    if (!m_ptrIActiveScript) { return E_POINTER; }
    if (!pResult) { return E_INVALIDARG; }
    EXCEPINFO ei = {0};
    CComPtr<IActiveScriptParse> ptrIActiveScriptParse;
    CHECKHR(m_ptrIActiveScript->QueryInterface(IID_IActiveScriptParse, (void **) &ptrIActiveScriptParse));
    CHECKHR(ptrIActiveScriptParse->ParseScriptText(szScript, strItemName, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, pResult, &ei));
    return m_ptrIActiveScript->SetScriptState(SCRIPTSTATE_CONNECTED);
}

HRESULT CSimpleScriptSite::Execute(LPCOLESTR szScript, LPCOLESTR strItemName)
{
    if (!m_ptrIActiveScript) { return E_POINTER; }
    EXCEPINFO ei = {0};
    CComPtr<IActiveScriptParse> ptrIActiveScriptParse;
    CHECKHR(m_ptrIActiveScript->QueryInterface(IID_IActiveScriptParse, (void **) &ptrIActiveScriptParse));
    CHECKHR(ptrIActiveScriptParse->ParseScriptText(szScript, strItemName, NULL, NULL, 0, 0, 0L, NULL, &ei));
    return m_ptrIActiveScript->SetScriptState(SCRIPTSTATE_CONNECTED);
}

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr = S_OK;
    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    CSimpleScriptSite *pScriptSite = new CSimpleScriptSite();
    hr = pScriptSite->OpenScriptEngine(OLESTR("Python"));
    hr = pScriptSite->Execute(OLESTR("print 'Hello World. 5 squared is: ' + str(5 * 5)"), NULL);
    hr = pScriptSite->CloseScriptEngine();
    hr = pScriptSite->Release();
    ::CoUninitialize();
    return 0;
}
+2

Source: https://habr.com/ru/post/1783431/


All Articles