electron: [Bug]: Link error for native c++ modules
Preflight Checklist
- I have read the Contributing Guidelines for this project.
- I agree to follow the Code of Conduct that this project adheres to.
- I have searched the issue tracker for a feature request that matches the one I want to file, without success.
Electron Version
13.1.4
What operating system are you using?
Windows
Operating System Version
Windows 10 Home (19042)
What arch are you using?
x64
Last Known Working Electron version
No response
Expected Behavior
The native module in the testcase gist should be able to link. The problematic part is the function v8::ArrayBuffer::GetBackingStore()
Actual Behavior
Linking fails with the error
error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::shared_ptr<class v8::BackingStore> __cd ecl v8::ArrayBuffer::GetBackingStore(void)" (__imp_?GetBackingStore@ArrayBuffer@v8@@QEAA?AV?$shared_ptr@VBackingStore@v8@@@std@@XZ) re ferenced in function "void __cdecl foobar(class v8::FunctionCallbackInfo<class v8::Value> const &)" (?foobar@@YAXAEBV?$FunctionCallbac kInfo@VValue@v8@@@v8@@@Z) [c:\Work\repro_bug_arraybuffer\build\foobar.vcxproj]
Testcase Gist URL
https://gist.github.com/TanninOne/d321ab1676798647cf672f08e78b88d8
Additional Information
Building the same module for node 14.17.1 works fine.
The error message, although cryptic, is correct: the header and link library shipped do not seem to match. the header declares GetBackingStore like this:
std::shared_ptr<BackingStore> GetBackingStore();
but the library exports this:
?GetBackingStore@ArrayBuffer@v8@@QEAA?AV?$shared_ptr@VBackingStore@v8@@@__1@std@@XZ
which demangles to
public: class std::__1::shared_ptr<class v8::BackingStore> __cdecl v8::ArrayBuffer::GetBackingStore(void) __ptr64
so as far as I understand it the namespace is different and thus the linker doesn’t find the function.
node.exe version 14.17.1 otoh exports
?GetBackingStore@ArrayBuffer@v8@@QEAA?AV?$shared_ptr@VBackingStore@v8@@@std@@XZ
aka
public: class std::shared_ptr<class v8::BackingStore> __cdecl v8::ArrayBuffer::GetBackingStore(void) __ptr64
which matches the declaration in v8.h exactly.
With prior versions of electron (up to 12 I think) we could use the deprecated function GetContent to get at the content of an ArrayBuffer but that function has been removed so until this is fixed, if I’m not completely mistaken, any native module that requires access to the content of an ArrayBuffer, including helper libraries like nan or nbind and all modules that depend on those will be broken.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 3
- Comments: 21 (10 by maintainers)
@VerteDinde, I find the decision to build Electron on Windows using a C++ runtime that it just out of beta instead of the MS C++ runtime highly unusual - but there is probably a good reason for it. But in this case, I suggest that you also include this runtime along the
node.libDLL import library so that native modules can link with it. Currently, if I want to port my native Node.js addon to Electron I have only two choices and both are horrible:std::shared_ptras some people in this thread didlibc++for WindowsAll of this renders the port of a native Node.js addon to Electron a huge undertaking and completely destroys the dream of simply launching
electron-rebuildand going for a cup of coffee.I ended up adding the following to my
node-gypconfig:And using the follow
#ifNot the most elegant or low cost solution, but hopefully that works as a stop gap while my users migrate to Node-API.
Is there a
#defthat can be used to tell if the module is being built for electron? My solution was a bit convoluted.Just a note: I’d recommend that all native modules use N-API and avoid nan, for this kind of reason. C++ ABIs are very difficult to stabilize. N-API is explicitly designed as a stable ABI target. https://nodejs.org/api/n-api.html
@somanuell That’s a sample of the neon project source.
Neon_Buffer_Datais a very small helper that gets the contents of the buffer:The result of
node::Buffer::Newgoes intolocaland thennode::Buffer::Datacan be used to get the buffer data out.Yep, using the same clang + std library that Electron uses to build is the safest way to build native modules that interact with the std library.