I'm trying to use std::format
in a mex file but get an unresolved external symbol
error when I use std
as a module.
// test_mex.cpp
#include "mex.h"
import std;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
std::string temp{std::format("{:.2f}", 21.234)};
mexPrintf("%s\n", temp.c_str());
plhs[0] = mxCreateDoubleMatrix(10, 10, mxREAL);
}
compiled with
!cl /std:c++latest /O2 /Oi /EHsc /MD /nologo /c -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt" -I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include" "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\modules\std.ixx"
mex -O COMPFLAGS="$COMPFLAGS -std:c++latest /O2 /Oi /EHsc /Wall /MD" test_mex.cpp;
gives this error
Error using mex
Creating library test_mex.lib and object test_mex.exp
test_mex.obj : error LNK2019: unresolved external symbol "public: static int const std::_General_precision_tables_2<double>::_Max_P" (?_Max_P@?$_General_precision_tables_2@N@std@@2HB) referenced in function "struct std::to_chars_result __cdecl std::_Floating_to_chars_general_precision<double>(char *,char * const,double,int)" (??$_Floating_to_chars_general_precision@N@std@@YA?AUto_chars_result@0@PEADQEADNH@Z)
test_mex.obj : error LNK2019: unresolved external symbol "public: static int const std::_General_precision_tables_2<float>::_Max_P" (?_Max_P@?$_General_precision_tables_2@M@std@@2HB) referenced in function "struct std::to_chars_result __cdecl std::_Floating_to_chars_general_precision<float>(char *,char * const,float,int)" (??$_Floating_to_chars_general_precision@M@std@@YA?AUto_chars_result@0@PEADQEADMH@Z)
test_mex.mexw64 : fatal error LNK1120: 2 unresolved externals
If you don't use std::format
and instead just specify the string, for example std::string temp{"test"}
it compiles and runs.
Furthermore, instead of using a module if you replace import std;
with #include <format>
again it compiles and runs.
I'm using the Microsoft Visual C++ 2022 compiler.
I do not have mex
installed, but I can reproduce your issue just with MSVC.
Here is simple test code (foo.cpp):
import std;
int main()
{
std::println("Foo");
std::vector<int> v{5, 5, 5};
std::println("v: {}", v);
}
And here are a powershel commands to reproduce same linking error:
PS C:\Users\marekr22\Downloads> cl /std:c++latest /EHsc /nologo /W4 "${env:VCToolsInstallDir}modules\std.ixx" .\foo.cpp
std.ixx
foo.cpp
Generating Code...
PS C:\Users\marekr22\Downloads> link .\foo.obj
Microsoft (R) Incremental Linker Version 14.44.35213.0
Copyright (C) Microsoft Corporation. All rights reserved.
foo.obj : error LNK2019: unresolved external symbol "public: static int const std::_General_precision_tables_2<double>::_Max_P" (?_Max_P@?$_General_precision_tables_2@N@std@@2HB) referenced in function "struct std::to_chars_result __cdecl std::_Floating_to_chars_general_precision<double>(char *,char * const,double,int)" (??$_Floating_to_chars_general_precision@N@std@@YA?AUto_chars_result@0@PEADQEADNH@Z)
foo.obj : error LNK2019: unresolved external symbol "public: static int const std::_General_precision_tables_2<float>::_Max_P" (?_Max_P@?$_General_precision_tables_2@M@std@@2HB) referenced in function "struct std::to_chars_result __cdecl std::_Floating_to_chars_general_precision<float>(char *,char * const,float,int)" (??$_Floating_to_chars_general_precision@M@std@@YA?AUto_chars_result@0@PEADQEADMH@Z)
foo.exe : fatal error LNK1120: 2 unresolved externals
Note this is same error as you are reporting when using mex
!
Now if you follow instruction from MSVC documentation you will see you need to link std.obj
.
So after correcting last command my example links correctly:
PS C:\Users\marekr22\Downloads> link .\foo.obj std.obj
Microsoft (R) Incremental Linker Version 14.44.35213.0
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\marekr22\Downloads> .\foo
Foo
v: [5, 5, 5]
So basically you should correct your mex
to link std.obj
.