gpt4 book ai didi

javascript - 如何修复 CoCreateInstance 读取访问冲突?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:04:02 26 4
gpt4 key购买 nike

我使用C++ MFC activex脚本调用javascript函数,它编译正常但使用 init 函数运行到 CoCreateInstance,导致读取访问冲突(此 0x4)。如何解决这个问题?

下面是我的代码:

//BasicScriptHost.cpp

#include "stdafx.h"
#include "DTCfg.h"
#include "BasicScriptHost.h"
#include <atlbase.h>
#include <string>
#include <atlfile.h>
using namespace std;

HRESULT BasicScriptHost::Init() {
CLSID clsJS;
HRESULT hr = ::CLSIDFromProgID(L"javascript", &clsJS);
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = ::CoCreateInstance(clsJS,NULL, CLSCTX_INPROC_SERVER,
IID_IActiveScript, (void**)&m_pEngine);//Error read access violation
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = m_pEngine.QueryInterface(&m_pEngineParse);
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = m_pEngineParse->InitNew();
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = m_pEngine->SetScriptSite(this);
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = m_pEngine->SetScriptState(SCRIPTSTATE_STARTED);
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = m_pEngine->SetScriptState(SCRIPTSTATE_CONNECTED);
if (FAILED(hr))
{
return SETERROR(hr);
}

return S_OK;
}

HRESULT BasicScriptHost::Close()
{
HRESULT hr = m_pEngine->SetScriptState(SCRIPTSTATE_DISCONNECTED);
if (FAILED(hr))
{
return SETERROR(hr);
}

hr = m_pEngine->SetScriptState(SCRIPTSTATE_CLOSED);
if (FAILED(hr))
{
return SETERROR(hr);
}
return S_OK;
}

HRESULT BasicScriptHost::AddScriptFile(string const& file)
{
CAtlFile atlfile;
HRESULT hr = atlfile.Create((LPCTSTR)file.c_str(), GENERIC_READ, 0,
OPEN_EXISTING);
if (FAILED(hr))
{
return SETERROR(hr);
}

ULONGLONG len;
hr = atlfile.GetSize(len);
if (FAILED(hr))
{
return SETERROR(hr);
}

LARGE_INTEGER li;
li.QuadPart = len;
CAutoVectorPtr<char> szData(new char[li.LowPart + 1]);
if (!szData)
{
return SETERROR(E_OUTOFMEMORY);
}

DWORD dwBytesRead;
hr = atlfile.Read(szData, li.LowPart, dwBytesRead);
if (FAILED(hr))
{
return SETERROR(hr);
}

szData[dwBytesRead] = '\0';
atlfile.Close(); USES_CONVERSION;
wstring script = A2W(szData); EXCEPINFO sEx;
hr = m_pEngineParse->ParseScriptText(script.c_str(), NULL, NULL,
NULL,
1, 0, SCRIPTTEXT_ISVISIBLE | SCRIPTTEXT_ISPERSISTENT, NULL,
&sEx);
if (FAILED(hr))
{
return SETERROR(hr);
}
return S_OK;
}

HRESULT BasicScriptHost::GetScriptDispatch(IDispatch** retval)
{
HRESULT hr = m_pEngine->GetScriptDispatch(NULL, retval);
if (FAILED(hr))
{
return SETERROR(hr);
}
return S_OK;
}

//BasicScriptHost.h

#define SETERROR(hr) hr
#include <string>
#include <vector>
#include <activscp.h>
#include <comdef.h>
#include <atlbase.h>

class BasicScriptHost : public IActiveScriptSite
{

// IActiveScriptSite
STDMETHOD(GetItemInfo)(LPCOLESTR /*pstrName*/, DWORD
/*dwReturnMask*/,
IUnknown **ppiunkItem, ITypeInfo **ppti)
{
*ppiunkItem = NULL;
*ppti = NULL;
return S_OK;
}

STDMETHOD(OnScriptError)(IActiveScriptError *pscripterror)
{
return S_OK;
}

STDMETHOD(GetLCID)(LCID *plcid)
{
*plcid = NULL;
return E_NOTIMPL;
}

STDMETHOD(GetDocVersionString)(BSTR* pbstrVersion)
{
*pbstrVersion = NULL;
return E_NOTIMPL;
}

STDMETHOD(OnScriptTerminate)(const VARIANT * /*pvr*/, const EXCEPINFO
* /*pei*/)
{
return S_OK;
}

STDMETHOD(OnStateChange)(SCRIPTSTATE /*ssScriptState*/)
{
return S_OK;
}

STDMETHOD(OnEnterScript)()
{
return S_OK;
}

STDMETHOD(OnLeaveScript)()
{
return S_OK;
}

public:
HRESULT Init();

HRESULT Close();

HRESULT AddScriptFile(std::string const& file);

HRESULT GetScriptDispatch(IDispatch** retval);

private:
// Script Engine Wrapper Interfaces
CComPtr<IActiveScript> m_pEngine;
CComPtr<IActiveScriptParse> m_pEngineParse;
};

//调用函数部分

::CoInitialize(NULL);

BasicScriptHost* host=NULL;

host->AddScriptFile("C:\\Users\\123.js");
host->Init();

CComPtr<IDispatch> pJs;
host->GetScriptDispatch(&pJs);
CComVariant var1(10);
CComVariant var2(20);
CComVariant ret;
pJs.Invoke2((LPCOLESTR)"add", &var1, &var2, &ret);
host->Close();
::CoUninitialize();

我想这可能是因为m_pEngine无效,但我不知道如何初始化m_pEngine

最佳答案

在对象未初始化时访问类成员变量会捕获异常。您应该实现 BasicScriptHost 构造函数和 IActiveScriptSite 的一些抽象函数,以便正确初始化变量 host

这是类声明的示例:

class BasicScriptHost : public IActiveScriptSite
{
ULONG ref;
public:
BasicScriptHost() : ref(1) { }

ULONG WINAPI AddRef() {
return InterlockedIncrement(&ref);
}

ULONG WINAPI Release(){
LONG refCount = InterlockedDecrement(&ref);
if (!refCount)
delete this;
return refCount;
}

HRESULT WINAPI QueryInterface(REFIID iid, void **ppvObject){
*ppvObject = 0;
if (iid == IID_IUnknown)
*ppvObject = (IUnknown*)(IActiveScriptSite*)this;
else if (iid == IID_IActiveScriptSite)
*ppvObject = (IActiveScriptSite*)this;
else if (iid == IID_IActiveScriptSiteWindow)
*ppvObject = (IActiveScriptSiteWindow*)this;
else
return E_NOINTERFACE;

AddRef();
return S_OK;
}

// ... your class body
}

变量host需要先初始化,使用后释放:

::CoInitialize(NULL);
BasicScriptHost * host = new BasicScriptHost();

host->AddScriptFile("C:\\Users\\123.js");
host->Init();

CComPtr<IDispatch> pJs;
host->GetScriptDispatch(&pJs);
CComVariant var1(10);
CComVariant var2(20);
CComVariant ret;

pJs.Invoke2((LPCOLESTR)"add", &var1, &var2, &ret);
pJs.Release(); //release CComPtr after used.

host->Close();
host->Release(); //The pointer will be deleted here or the program has a memory leak

::CoUninitialize();

关于javascript - 如何修复 CoCreateInstance 读取访问冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53942662/

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