我正在构建一个用C ++编写的窗口应用程序。我想使用几个python库。
我不需要任何花哨的Python互操作。我的方法是这样的:
打开一个线程来运行Python解释器。
将命令从C ++发送到Python解释器。 C ++可能需要为interop编写一些中间文件。
这种方法很脏,但它适用于许多类似解释器的环境,例如: gnuplot,lua。
我的问题是,我可以使用哪种API来执行此任务。也许我需要一些Win32 API?
编辑:我不需要任何特定的Python。我真的想要一般的方法。所以我的应用程序也可以使用gnuplot等。
答案 0 :(得分:4)
如果您拥有Python的源代码分发,则可以在Demo/embed
目录中查找示例。相关文档为here。
答案 1 :(得分:2)
ActivePython(http://www.activestate.com/activepython/downloads)将自身安装为ActiveScript引擎.ProgID是Python.AXScript.2。因此,您可以通过Windows标准IActiveScript接口与COM一起使用它。阅读它。
分配是另一回事。你需要客户拥有它,或者你可以尝试从ActiveState的软件包中提取多汁的部分,或者可能有官方的方式来进行无人值守的设置......
答案 2 :(得分:2)
我已经整理了一个“Hello World”IActiveScript C ++ ATL控制台应用程序:
CSimpleScriptSite
IActiveScriptSite
和IActiveScriptSiteWindow
Python
界面在IActiveSite
引擎上调用CoCreateInstance Python
声明print 'Hello World. 5 squared is: ' + str(5 * 5)
Python
。您应该咨询MSDN IActiveScriptError return S_OK;
实施的功能Python
,它提供了Python解释器IActiveScript
包装器IActiveScript
的Python解释器,您只需要更新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;
}
答案 3 :(得分:0)
您还可以使用boost Python:http://www.boost.org/doc/libs/1_45_0/libs/python/doc/index.html