【问题标题】:C++ - Qt + v8 under msvc2012C++ - msvc2012下的Qt + v8
【发布时间】:2013-08-01 10:06:52
【问题描述】:

最近,我在Qt5.1.0下启动了一个项目。
经过一番开发,我选择用Google V8Javascript下制作一个脚本系统。
Windows 7 x64 下,编译 V8 的唯一方法是在 msvc2012 下,我有 3 个 .lib 文件可以使用。
仅使用 V8 的单个项目中,一切正常。但是将 V8 与使用 Qt5 的现有项目集成起来有点复杂。

这是我正在使用的最小代码示例:(当然,这个项目中还有更多文件......)

#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();
}

此时,我遇到了很多这种类型的链接错误:

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

好像Qt是用/MDd标志编译的,而V8只能编译/MTd标志。

经过大量研究和测试,我找不到任何东西...
有人有解决这个问题的线索吗?

提前致谢。

【问题讨论】:

  • 如果您完全确定 V8 可以使用/MTd 编译(他们为什么要这样做?),那么唯一的解决方案是也使用该标志编译 Qt .没有办法afaik。

标签: c++ qt visual-c++ linker v8


【解决方案1】:

Google V8 默认使用MT 标志构建,因此与使用MD 标志构建的Qt 不兼容。

使用 Qt 构建 V8 的技巧是在 Visual Studio 中使用 MD 标志进行 V8 编译。您可以通过以下方式做到这一点:

  1. 通过执行 build\gyp_v8.py 生成 Visual Studio 项目。
  2. 使用 Visual Studio 打开 all.sln。
  3. 在解决方案的所有项目中设置 MD 标志:属性 > C/C++ > 代码生成 > 运行时库 > 多线程 DLL (/MD)
  4. 然后重建解决方案
  5. 您将获得与 QtCreator 一起使用的正确 lib 文件。

在 QtCreator 中进行 V8 库的链接:

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

您还需要链接WinMM.libWS2_32.libadvapi32.lib,它们通常位于:C:\Program Files (x86)\Windows Kits\

这使它在我的系统上。我希望它可以帮助其他有同样问题的人。

【讨论】:

  • 这样做有什么缺点吗?我读到谷歌专门选择 /MT 来减少依赖关系,但它的改变是否足够重要以至于它可能会导致问题?
【解决方案2】:

好吧,我无法以这种方式使用 V8 和 Qt5,即使在多次尝试以静态方式构建 Qt 之后。

所以,我为 V8 编写了一个 .dll 包装器,它可以集成到我在 QtCreator 上的项目中。

这是我的包装:

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;
}

我有 WrapTest.hhV8_Wrapper.libV8_Wrapper.dll,并将 .lib 添加到我的 .pro文件到我的 Qt5 项目中:

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

在我的 Qt 项目中,main.cpp 文件:

#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();
}

这在标准输出中给了我:

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

如果你有需要,我希望这个解决方案可以帮助你^_^

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2013-05-10
    • 1970-01-01
    相关资源
    最近更新 更多