- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我使用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/
以下是简短的重现样本: DWORD WINAPI _threadTest (LPVOID) { Sleep (2000); CoInitialize(0); CoCreateI
我是 .NET 程序员和 COM 新手。想简单了解一下 CoCreateInstance 的作用是什么? 最佳答案 你可以想到CoCreateInstance()作为匿名工厂类的接口(interfac
我有一个调用 CoCreateInstance 的函数。此函数被多次调用并且有效,但是有一次 CoCreateInstance 因“变量类型错误”错误而失败。问题是参数在成功和失败时始终相同。什么会导
我尝试用 direct2d 制作位图。问题是 CoCreateInstance(...) 函数不起作用 HRESULT Renderer::InitImagingFactory() { if
我正在使用开源库 EasyHook . 我想做的是,当 VB6 应用程序在特定 CLSID 上从 ole32.dll 调用 CoCreateInstance 时 Hook ,返回我自己的对象 C# 实
我有一个 DLL,我需要在其中调用 CoCreateInstance()。在 Dllmain() 中,我创建了一个新线程来运行我的函数 do_stuff()。 CoCreateInstance() 在
我有一个 Windows 服务,它在初始化期间调用多个 COM+。在某些系统上,此 Windows 服务会在启动期间导致死锁。 At least one service or driver faile
使用 COM 你使用 CoCreateInstance创建一个对象。 有没有办法完全破坏它,以便单元测试的下一部分可以重新开始? 最佳答案 每个持有引用的 COM 接口(interface)指针的人都
我正在尝试使用 Windows 核心音频 API 从麦克风捕获音频 相关的代码行是 const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEn
我正在将一段代码从 C++ 转换为 C#,但不确定如何使用 CoCreateInstance()。这是 C++(这有效并且是我在 C# 中想要的): IComDevice *Device=NULL;
我在这里尝试做的只是创建一个接口(interface)的实例。真的应该这么简单。一直在关注任何在线资料,阅读我能找到但终生无法解决这个问题的资料。 它归结为从 CoCreateInstance 返回的
我有一个关于 CoCreateInstnace() 方法如何定位和创建包含在 COM DLL 中的 CoClass 实例的问题。 根据MSDN : The CoCreateInstance funct
我使用C++ MFC activex脚本调用javascript函数,它编译正常但使用 init 函数运行到 CoCreateInstance,导致读取访问冲突(此 0x4)。如何解决这个问题? 下面
我正在使用 COM 通过 C++ 非托管代码初始化 C# .NET 类,并且即使在非常基本的程序中我也检测到内存泄漏: int _tmain(int argc, _TCHAR* argv[]) {
这是创建 COM 对象的代码示例: CComPtr pFilter; auto hr = CoCreateInstance(CLSID_DMOWrapperFilter, NULL, CLSC
鉴于一些现有代码调用 CoCreateInstance 来创建已注册 COM 对象的实例,是否有一种方法可以重定向这些调用以创建不同的实例? 想法是在同一个进程中(出于测试目的),在不改变原始代码或影
我想使用 DSound Audio Render在我的一个应用程序中,所以我用 CoCreateInstance 加载它.根据my previous question ,如果我没有安装音频硬件,CoC
当我调用 dll 中的 CoCreateInstance() 时,出现错误“不支持此类接口(interface)”。我正在尝试创建 IGroupPolicyObject 的实例。当我通过 exe 运行
我已经成功编译并注册了一个直接显示过滤器。现在我想在我的代码中使用它。但是对 COCreateInstance 的调用返回错误代码 E_NOINTERFACE。 这是我的过滤器的注册码 #inclu
以上是否可行? 我可以这样做吗: IUnknown *punk; punk->QueryInterface(IID_MyInterface, (void**)&m_pMyInterface); 我认为
我是一名优秀的程序员,十分优秀!