c++matlabmex

std::format in a mex file


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.


Solution

  • 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.