V8引擎静态库及其调用方法

本V8引擎静态库分为x86版本和x64版本

V8引擎静态库下载地址
编译工具:VS2019

v8开头的即为V8引擎静态库(附送其它开源静态库libuv.lib、zlib.lib等_
在这里插入图片描述

在这里插入图片描述
如何调用V8引擎
1、下载v8静态库到本地
2、配置开发环境
将上述v8的include目录配置到“附加包含目录”配置项中
在这里插入图片描述
根据你的开发环境配置不同版本的lib库(注意debug和release),如下:
在这里插入图片描述
3、调用代码如下,需要创建一个控制台程序


#include <iostream>
#include "v8.h"
#include "libplatform/libplatform.h"
#include <assert.h>
#include <windows.h>

#pragma comment(lib, "winmm.lib") 
#pragma comment(lib, "dbghelp.lib") 
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "v8_compiler.lib") 
#pragma comment(lib, "v8_libbase.lib") 
#pragma comment(lib, "v8_snapshot.lib") 
#pragma comment(lib, "v8_libplatform.lib") 
#pragma comment(lib, "v8_libsampler.lib") 
#pragma comment(lib, "v8_init.lib") 
#pragma comment(lib, "v8_initializers.lib") 
#pragma comment(lib, "v8_zlib.lib") 

#pragma comment(lib, "icudata.lib") 
#pragma comment(lib, "icutools.lib") 
#pragma comment(lib, "icuucx.lib") 
#pragma comment(lib, "icui18n.lib") 
#pragma comment(lib, "v8_base_without_compiler.lib") 
using namespace v8;
using namespace std;

wstring Utf8ToUnicode(const string& strSrc)
{
	/*!< 分配目标空间 */
	int iAllocSize = static_cast<int>(strSrc.size() + 10);
	WCHAR* pwszBuffer = new WCHAR[iAllocSize];
	if (NULL == pwszBuffer)
	{
		return L"";
	}
	int iCharsRet = MultiByteToWideChar(CP_UTF8, 0, strSrc.c_str(),
		static_cast<int>(strSrc.size()),
		pwszBuffer, iAllocSize);
	/*!< 成功 */
	wstring wstrRet;
	if (0 < iCharsRet)
	{
		wstrRet.assign(pwszBuffer, static_cast<size_t>(iCharsRet));
	}

	/*!< 释放内存 */
	delete[] pwszBuffer;

	return wstrRet;
}
string Utf8ToAnsi(const string& strSrc)
{
	wstring wstrTemp = Utf8ToUnicode(strSrc);

	/*!< 分配目标空间, 长度为 Ansi 编码的两倍 */
	int iAllocSize = static_cast<int>(strSrc.size() * 2 + 10);
	char* pszBuffer = new char[iAllocSize];
	if (NULL == pszBuffer)
	{
		return "";
	}
	int iCharsRet = WideCharToMultiByte(CP_ACP, 0, wstrTemp.c_str(),
		static_cast<int>(wstrTemp.size()),
		pszBuffer, iAllocSize, NULL, NULL);
	/*!< 成功 */
	string strRet;
	if (0 < iCharsRet)
	{
		strRet.assign(pszBuffer, static_cast<size_t>(iCharsRet));
	}

	/*!< 释放内存 */
	delete[] pszBuffer;

	return strRet;
}

string UnicodeToUtf8(const wstring& wstrSrc)
{
	/*!< 分配目标空间, 一个16位Unicode字符最多可以转为4个字节 */
	int iAllocSize = static_cast<int>(wstrSrc.size() * 4 + 10);
	char* pszBuffer = new char[iAllocSize];
	if (NULL == pszBuffer)
	{
		return "";
	}
	int iCharsRet = WideCharToMultiByte(CP_UTF8, 0, wstrSrc.c_str(),
		static_cast<int>(wstrSrc.size()),
		pszBuffer, iAllocSize, NULL, NULL);
	/*!< 成功 */
	string strRet;
	if (0 < iCharsRet)
	{
		strRet.assign(pszBuffer, static_cast<size_t>(iCharsRet));
	}

	/*!< 释放内存 */
	delete[] pszBuffer;

	return strRet;
}

string AnsiToUtf8(const string& strSrc)
{
	/*!< 分配目标空间, 长度为 Ansi 编码的两倍 */
	int iAllocSize = static_cast<int>(strSrc.size() * 2 + 10);
	WCHAR* pwszBuffer = new WCHAR[iAllocSize];
	if (NULL == pwszBuffer)
	{
		return "";
	}
	int iCharsRet = MultiByteToWideChar(CP_ACP, 0, strSrc.c_str(),
		static_cast<int>(strSrc.size()),
		pwszBuffer, iAllocSize);
	/*!< 成功 */
	wstring wstrTemp;
	if (0 < iCharsRet)
	{
		wstrTemp.assign(pwszBuffer, static_cast<size_t>(iCharsRet));
	}

	/*!< 释放内存 */
	delete[] pwszBuffer;

	return UnicodeToUtf8(wstrTemp);
}


Local<String> ToLocalString(Isolate* isolate, const unsigned char* pData, int iDataLen)
{
	return String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(pData),
		NewStringType::kNormal, iDataLen).ToLocalChecked();

}

class CPerson
{

public:
	CPerson(int iAge = 0) {
		m_iAge = iAge;
		m_pszName = "小ming";
	}
	virtual ~CPerson() {
		printf("============~CPerson()============\n");
	};

	static void New(const FunctionCallbackInfo<Value>& args)
	{
		assert(args.IsConstructCall());

		Isolate* isolate = args.GetIsolate();

		int iAge = 0;
		if (args.Length() > 0)
			iAge = args[0].As<Int32>()->Value();

		Handle<Object> object = args.Holder();

		object->SetInternalField(0, External::New(isolate, new CPerson(iAge)));

	}

public:
	static void GetAge(const FunctionCallbackInfo<Value>& args)
	{
		// 通过参数args获取Wrap对象
		Local<Object> self = args.Holder();
		Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
		void* ptr = wrap->Value();

		CPerson* pThis = static_cast<CPerson*>(ptr);

		args.GetReturnValue().Set(pThis->m_iAge);
	}

	static void GetName(const FunctionCallbackInfo<Value>& args)
	{
		// 通过参数args获取Wrap对象
		Local<Object> self = args.Holder();
		Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
		void* ptr = wrap->Value();

		Isolate* isolate = args.GetIsolate();
		CPerson* pThis = static_cast<CPerson*>(ptr);

		string strUTF8 = AnsiToUtf8(pThis->m_pszName);
		Local<String> strName = String::NewFromUtf8(isolate, strUTF8.c_str(),
			NewStringType::kInternalized).ToLocalChecked();
		//Local<String> strName = ToLocalString(isolate, (const unsigned char*)pThis->m_pszName, strlen(pThis->m_pszName));
		args.GetReturnValue().Set(strName);
	}


public:
	int m_iAge;
	const char* m_pszName;
};


void TestFuncByJsCall(const FunctionCallbackInfo<Value>& args)
{
	Isolate* isolate = args.GetIsolate();
	int iLen = args.Length();
	if (iLen != 2)
		return;

	if (!args[0]->IsInt32())
		return;
	if (!args[1]->IsString())
		return;
	Local<Context> context = isolate->GetCurrentContext();
	int i = 0;
	args[0]->Int32Value(context).To(&i);
	String::Utf8Value str(isolate, args[1]);


	//cout << *str << "\n";
	cout << "进入函数:" << __FUNCTION__ << "(" << i << ", \"" << *str << "\")" << "\n";
	args.GetReturnValue().Set(100);
}


class PersistentToLocal
{
public:
	// If persistent.IsWeak() == false, then do not call persistent.Reset()
	// while the returned Local<T> is still in scope, it will destroy the
	// reference to the object.
	template <class TypeName>
	static inline v8::Local<TypeName> Default(v8::Isolate* isolate,
		const v8::PersistentBase<TypeName>& persistent) {
		if (persistent.IsWeak()) {
			return PersistentToLocal::Weak(isolate, persistent);
		}
		else {
			return PersistentToLocal::Strong(persistent);
		}
	}

	// Unchecked conversion from a non-weak Persistent<T> to Local<T>,
// use with care!
//
// Do not call persistent.Reset() while the returned Local<T> is still in
// scope, it will destroy the reference to the object.
	template <class TypeName>
	static inline v8::Local<TypeName> Strong(
		const v8::PersistentBase<TypeName>& persistent) {
		return *reinterpret_cast<v8::Local<TypeName>*>(
			const_cast<v8::PersistentBase<TypeName>*>(&persistent));
	}

	template <class TypeName>
	static inline v8::Local<TypeName> Weak(
		v8::Isolate* isolate,
		const v8::PersistentBase<TypeName>& persistent) {
		return v8::Local<TypeName>::New(isolate, persistent);
	}
};


int main(int argc, char* argv[])
{
	cout << argv[0] << "\n";
	// V8初试化.
	V8::InitializeICU();

	// 加载快照文件:natives_blob.bin、snapshot_blob.bin
	V8::InitializeICUDefaultLocation(argv[0]);
	//V8::InitializeExternalStartupData(argv[0]);
//	V8::InitializeExternalStartupDataFromFile("E:/VS2019/TestV8/x64/Debug/natives_blob.bin");
//	V8::InitializeExternalStartupDataFromFile("E:/VS2019/TestV8/x64/Debug/snapshot_blob.bin");

	// 生成一个默认的platform对象
	std::unique_ptr<Platform> platform = platform::NewDefaultPlatform();
	// 初始化platform
	V8::InitializePlatform(platform.get());
	// V8的初始化
	V8::Initialize();


	std::ofstream trace_file;
	platform::InProcessStackDumping in_process_stack_dumping = // v8::platform::InProcessStackDumping::kDisabled;
		platform::InProcessStackDumping::kEnabled;

	// 创建isolate.
	Isolate::CreateParams create_params;
	create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator();
	Isolate* isolate = Isolate::New(create_params);
	{
		HandleScope scope(isolate);

		// start v8 trace
		//platform::tracing::TraceConfig* trace_config;
		//trace_config = v8::platform::tracing::TraceConfig::CreateDefaultTraceConfig();
		//tracing_controller->StartTracing(trace_config);

		Local<Context> context = Context::New(isolate);
		Context::Scope context_scope(context);

		/
		// 一、执行JS脚本中的函数
		/
		Local<String> source = String::NewFromUtf8(isolate,
			"function add(a, b){   var vmap = new Map(); vmap.set(\"123\", 1234); return vmap.get(\"123\");} add(1,1);",
			NewStringType::kNormal).ToLocalChecked();

		Local<Script> script = Script::Compile(context, source).ToLocalChecked();
		Local<Value> result = script->Run(context).ToLocalChecked();
		if (result->IsNumber())
			std::cout << "Test V8 jet : add(1,1) = " << Int32::Cast(*result)->Value() << "\n";


		//const char* pszFuncName = "func";
		//Local<String> strFuncName = ToLocalString(isolate, (const unsigned char*)pszFuncName, strlen(pszFuncName));


		/
		// 二、JS调用C函数
		/
		//Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
		//global_template->Set(isolate, "TestFunc", FunctionTemplate::New(isolate, TestFuncByJsCall));

		context->Global()->Set(context, String::NewFromUtf8(isolate, "TestFunc").ToLocalChecked(),
			Function::New(context, TestFuncByJsCall).ToLocalChecked()).FromJust();
		Local<String> jsCall = String::NewFromUtf8(isolate,
			"TestFunc(1, 'Call From C++');", NewStringType::kNormal).ToLocalChecked();

		Local<Script> scriptFunc;
		Local<Value> ret;
		if (Script::Compile(context, jsCall).ToLocal(&scriptFunc) &&
			scriptFunc->Run(context).ToLocal(&ret))
		{

			if (ret->IsNumber())
				std::cout << "Test V8 jet : TestFuncByJsCall = " << Int32::Cast(*ret)->Value() << "\n";
		}

		/
		// 三、JS调用C++类
		/
		Local<FunctionTemplate> clsPerson = FunctionTemplate::New(isolate, CPerson::New,
			Local<Value>(), Local<Signature>(), 0,
			ConstructorBehavior::kAllow, SideEffectType::kHasSideEffect);
		const char* pszClsName = "Person";
		Local<String> clsName = ToLocalString(isolate, (const unsigned char*)pszClsName, strlen(pszClsName));
		clsPerson->SetClassName(clsName);
		Local<ObjectTemplate> objPerson = clsPerson->InstanceTemplate();
		objPerson->SetInternalFieldCount(1);
		// 1、设置CPerson类的构造函数到全局Global中
		context->Global()->Set(context, clsName, clsPerson->GetFunction(context).ToLocalChecked()).Check();

		// 2、设置GetAge方法到CPerson类中
		Local<Signature> signature = Signature::New(isolate, clsPerson);
		Local<String> NameGetAge = String::NewFromUtf8(isolate, "GetAge",
			NewStringType::kInternalized).ToLocalChecked();

		Local<FunctionTemplate> t = FunctionTemplate::New(isolate, CPerson::GetAge);
		/*Local<Value>(), signature, 0, ConstructorBehavior::kThrow,
		SideEffectType::kHasSideEffectToReceiver);*/

		clsPerson->PrototypeTemplate()->Set(NameGetAge, t);
		//clsPerson->PrototypeTemplate()->Set(isolate, "GetAge", t);
		t->SetClassName(NameGetAge);
		objPerson->Set(isolate, "GetAge", t);
		objPerson->Set(isolate, "GetName", FunctionTemplate::New(isolate, CPerson::GetName));


		//	PersistentBase<FunctionTemplate>::Strong(Person_NEW);
		// 3、执行脚本
		Local<String> jsPerson = String::NewFromUtf8(isolate,
			" var Values; "
			" function TestPerson(i){	var person = new Person(i); "
			" Values = person.GetName(); "
			//" person.GetPage = OnGetPage();"
			" person = null; return Values;	 "
			"}	"
			"TestPerson(42);",
			NewStringType::kNormal).ToLocalChecked();
		// return person.GetAge();
		Local<Script> scriptClass;
		Local<Value> retClass;
		if (Script::Compile(context, jsPerson).ToLocal(&scriptClass) &&
			scriptClass->Run(context).ToLocal(&retClass))
		{
			if (retClass->IsNumber())
				std::cout << "Test V8 jet : Person = GetAge() " << Int32::Cast(*retClass)->Value() << "\n";
			else if (retClass->IsString())
			{
				String::Utf8Value str(isolate, retClass);
				string strName = Utf8ToAnsi(*str);
				std::cout << "Test V8 jet : Person = GetName() " << strName.c_str() << "\n";
			}
			// C++调用JS中的变量和函数
			Local<String> strValues = String::NewFromUtf8(isolate, "Values", NewStringType::kNormal).ToLocalChecked();
			Local<Value> jsValues = context->Global()->Get(context, strValues).ToLocalChecked();
			Local<Value> jsFunc = context->Global()->Get(context,
				String::NewFromUtf8(isolate, "TestPerson", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked();
			if (jsValues.IsEmpty())
				printf("empty\n");
			else if (jsValues->IsInt32())
			{
				int iAge = jsValues.As<Int32>()->Value();
				printf("C++ Call JS values: %d\n", iAge);
			}
			else if (jsValues->IsString())
			{
				String::Utf8Value str(isolate, jsValues);
				string strName = Utf8ToAnsi(*str);
				printf("C++ Call JS values: %s\n", strName.c_str());
			}

			if (jsFunc->IsFunction())
			{
				Local<Function> callback = jsFunc.As<Function>();
				Local<Value> recv = Undefined(isolate);
				Local<Value> ret_v;
				Local<Value> argv[1];
				argv[0] = Integer::New(isolate, 56);
				callback->Call(context, recv, 1, argv).ToLocal(&ret_v);
				if (ret_v->IsString())
				{
					String::Utf8Value str(isolate, ret_v);
					string strName = Utf8ToAnsi(*str);
					printf("C++ Call JS Fuction: %s\n", strName.c_str());
				}

			}
		} // end JS调用C++类
	}
	char c;
	std::cin >> c;

	// 关掉v8.
	isolate->Dispose();
	V8::Dispose();
	V8::ShutdownPlatform();
	platform.reset();
}