Search code examples
c++visual-studio-2010c++-cliv8

LNK2001 trying to use v8 from Visual Studio C++CLI project


When building a simple hello-world-style project trying to embed v8 I get an

error LNK2001: ""public: static class v8::Local __cdecl v8::String::New(char const *,int)" (?New@String@v8@@SA?AV?$Local@VString@v8@@@2@PEBDH@Z)"

Something's wrong with my project settings and I can't seem to figure it out. This is my source file:

#include "stdafx.h"
#include "v8.h"

using namespace System;

#pragma unmanaged

void test()
{
    v8::Local<v8::String> source = v8::String::New("'Hello' + ', World'");
}

#pragma managed

int main(array<System::String ^> ^args)
{
    return 0;
}

Compiling seems to work fine, I added the v8 directory of the node 0.8.0 project (node-v0.8.0\deps\v8\include). In terms of linking, I added these libs as additional dependencies.

node-v0.8.0\Release\lib\v8_base.lib
node-v0.8.0\Release\lib\v8_snapshot.lib

I'm on Windows 7, 64 bit. My project is set to build x64, as is node.js (installed using the 'Windows x64 installer'). What's wrong?

Update I figured that when building for x64, the additional dependencies I added are completely ignored (the error messages are the same whether I add them or not). But when building for win32, I get different error messages. (Btw: Does that mean the lib files are for x86 and not x64 - as I assumed - and why didn't the linker tell me so? Update: dumpbin told me, the lib files are indeed for x86).

In addition to v8_base and v8_snapshot, the linker errors lead me to add

winmm.lib
ws2_32.lib

Which gets rid of all "unresolved external symbol" errors. But now I get a LNK2005 "already defined" error:

エラー 1   error LNK2005: __matherr は既に LIBCMT.lib(_matherr_.obj) で定義されています。   c:\...\HelloC++CLIWorld\HelloC++CLIWorld\MSVCRTD.lib(merr.obj)  HelloC++CLIWorld

I tried /NODEFAULTLIB:LIBCMT, then I get an LNK2001 "unresolved external symbol":

エラー 1   error LNK2001: 外部シンボル "__HUGE" は未解決です。  c:\...\HelloC++CLIWorld\HelloC++CLIWorld\v8_base.lib(heap.obj)  HelloC++CLIWorld

I also tried `/NODEFAULTLIB:MSVCRTD', but then I get tons of LNK2001s again. A tiny selection:

エラー 1   error LNK2001: 外部シンボル "___native_dllmain_reason" は未解決です。    c:\...\HelloC++CLIWorld\HelloC++CLIWorld\MSVCMRTD.lib(mstartup.obj) HelloC++CLIWorld
エラー 2   error LNK2001: 外部シンボル "___native_vcclrit_reason" は未解決です。    c:\...\HelloC++CLIWorld\HelloC++CLIWorld\MSVCMRTD.lib(mstartup.obj) HelloC++CLIWorld
エラー 3   error LNK2001: 外部シンボル "___native_startup_state" は未解決です。 c:\...\HelloC++CLIWorld\HelloC++CLIWorld\MSVCMRTD.lib(mstartup.obj) HelloC++CLIWorld
エラー 4   error LNK2001: 外部シンボル "___native_startup_lock" は未解決です。  c:\...\HelloC++CLIWorld\HelloC++CLIWorld\MSVCMRTD.lib(mstartup.obj) HelloC++CLIWorld
エラー 5   error LNK2001: 外部シンボル ""extern "C" int __cdecl __wgetmainargs(int *,wchar_t * * *,wchar_t * * *,int,struct _startupinfo *)" (?__wgetmainargs@@$$J0YAHPAHPAPAPA_W1HPAU_startupinfo@@@Z)" は未解決です。 c:\...\HelloC++CLIWorld\HelloC++CLIWorld\MSVCMRTD.lib(ManagedMain.obj)  HelloC++CLIWorld

Now what?


Solution

  • I figured out 2 things:

    • Visual Studio will not complain about the wrong architecture in a lib file you add to the linker settings as additional dependencies, but just ignore the file (I think I'm running at the default warning levels)
    • using dumpbin mylib.lib /headers|more revealed that the libs I thought were built for x64 were in fact built for x86

    As written in the Update part of my question, I could not get an x86 build to work, due to LNK2005 errors, but linking worked when I built for x64 against a x64 v8 lib (or rather, node.lib, which contains v8).

    The bad news: After having managed the compilation step, and now the linking step, I get a runtime exception, even when I, as I'm supposed to do, do a

    HandleScope handle_scope;
    

    before new'ing the v8::String. But that's for another question. For now, linking is solved, at least on x64. Oh happy day!