C++ - Qt + v8 under msvc2012

匿名 (未验证) 提交于 2019-12-03 08:56:10

问题:

Recently, I've started a project under Qt5.1.0.
After some development, I choose to make a scripting system under Javascript with Google V8.
Under Windows 7 x64, the only way to compile V8 is under msvc2012, and I got 3 .lib files to use.
In a single project using ONLY V8, everything works well. But integrating V8 with an existent project using Qt5 it's a bit more complicated.

Here is an example of a minimal code I'm using : (Of course, there is more file in this project...)

#include <QApplication>  #include <v8.h>  using namespace v8;  int v8_test() {   Isolate* isolate = Isolate::GetCurrent();   HandleScope handle_scope(isolate);   Handle<Context> context = Context::New(isolate);   Persistent<Context> persistent_context(isolate, context);   Context::Scope context_scope(context);   Handle<String> source = String::New("'Hello' + ', World!'");   Handle<Script> script = Script::Compile(source);   Handle<Value> result = script->Run();   persistent_context.Dispose();   String::AsciiValue ascii(result);   printf("%s\n", *ascii);   return 0; }  int main(int ac, char **av) {     std::cout<<"Starting application"<<std::endl;     QApplication app(ac, av);      v8_test();      //Do something else      return app.exec(); } 

At this point, I got a lot of linking errors of this type :

1>v8_base.x64.lib(api.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in moc_aCertainFile.obj 1>v8_base.x64.lib(v8threads.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in moc_aCertainFile.obj 1>v8_base.x64.lib(checks.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in moc_aCertainFile.obj 

It seems that Qt was compiled with /MDd flag, and V8 can only be compiled /MTd flag.

After lot of research and testing, I was unable to find anything...
Anyone got a clue to resolve this problem?

Thanks in advance.

回答1:

Google V8 is built by default with MT flag and consequently incompatible with Qt which is build with MD flag.

The trick to get it to build V8 with Qt is to make the V8 compilation in visual studio with MD flag. You can do this with the following:

  1. Generate the Visual Studio projects by executing build\gyp_v8.py.
  2. Open all.sln with Visual Studio.
  3. In all projects from the solution set the MD flag: properties > C/C++ > Code Generation > Runtime Library > Multi-threaded DLL (/MD)
  4. After that rebuild the solution
  5. You will get the correct lib files to use with QtCreator.

In QtCreator proceed with the linkage of V8 libraries:

LIBS += -L/PATH_TO_LIBRARIES/ -lv8_base.ia32 -licui18n -licuuc -lv8_nosnapshot.ia32 -lv8_snapshot 

You need also to link with WinMM.lib, WS2_32.lib and advapi32.lib, they are normally found in: C:\Program Files (x86)\Windows Kits\

This made it on my system. I hope it helps other people with the same problem.



回答2:

Well, I was unable to use V8 and Qt5 in this way, even after many tries to build Qt in static.

So, I wrote a .dll wrapper for V8, which can be integrated into my project on QtCreator.

Here is my wrapper :

WrapTest.hh:

#ifndef WRAPTEST_HH_ #define WRAPTEST_HH_  #include <iostream>  namespace v8w {      class WrapTest {     public:         static __declspec(dllexport) void   hello();     }; }  #endif /* WRAPTEST_HH_ */ 

WrapTest.cpp:

#include <v8.h>  #include "WrapTest.hh"  void    v8w::WrapTest::hello() {     std::cout<<"Hello, i'm V8 wrapper! :D"<<std::endl;     v8::Isolate* isolate = v8::Isolate::GetCurrent();     v8::HandleScope handle_scope(isolate);     v8::Handle<v8::Context> context = v8::Context::New(isolate);     v8::Persistent<v8::Context> persistent_context(isolate, context);     v8::Context::Scope context_scope(context);     v8::Handle<v8::String> source = v8::String::New("'Hello' + ', World!'");     v8::Handle<v8::Script> script = v8::Script::Compile(source);     v8::Handle<v8::Value> result = script->Run();     persistent_context.Dispose();     v8::String::AsciiValue ascii(result);     printf("%s\n", *ascii);     std::cout<<"End v8w::WrapTest::hello()"<<std::endl; } 

I've got WrapTest.hh, V8_Wrapper.lib and V8_Wrapper.dll, and a add the .lib to my .pro file into my Qt5 project :

LIBS += -L"$$_PRO_FILE_PWD_/lib"\         -lV8_Wrapper 

In my Qt project, the main.cpp file :

#include <iostream>  #include <QApplication>  #include "WrapTest.hh"  void testV8() {     std::cout<<"test"<<std::endl;     v8w::WrapTest::hello(); }  int main(int ac, char **av) {     std::cout<<"Starting application"<<std::endl;     QApplication app(ac, av);         testV8();      return app.exec(); } 

Which gave me in the standard output :

Starting application test Hello, i'm V8 wrapper! :D Hello, World! End v8w::WrapTest::hello() 

I hope this solution can help you if you're in the need ^_^



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!