I cannot place that function in a common project, because if I make it inline in a header file in the common project then another error because EMC_VERIFY is cross-platform such as on Windows, it requires MessageBox and MB_OK, and the most difficult is it requires "Windows.h" which is the most difficult to place, because I must always place it as last include.
So I don't make it inline by declaring in a header file and put the definition in a .cpp file as below, and I got errors, I'm sure it's because I'm using a template
.
Location: Project "emc-common" > "emc-common_internal.h"
template<typename... Args>
string string_sprintf(const char *format, Args... args);
Location: Project "emc-common" > "emc-common_internal.cpp"
template<typename... Args>
string string_sprintf(const char *format, Args... args) {
// Originated from https://learn.microsoft.com/en-us/answers/questions/813614/how-to-printf-to-stdstring-by-using-of-a-function.html
int length = std::snprintf(nullptr, 0, format, args...);
EMC_VERIFY(length >= 0);
size_t sz = length + 1; // Extra space for '\0'
char *buf = (char *)malloc(sz);
std::snprintf(buf, sz, format, args...);
string str = buf;
SAFE_FREE(buf);
return str;
}
Location: Project "emc-language" > "emc-language.cpp"
string g_output = "";
#define print(...) \
do { \
g_output += string_sprintf(__VA_ARGS__); \
} while(0)
Error:
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<char const *>(char const *,char const *)" (??$string_sprintf@PEBD@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBD0@Z) referenced in function "void __cdecl printBuiltin(struct emcl::astBuiltin *)" (?printBuiltin@@YAXPEAUastBuiltin@emcl@@@Z)
`
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<char *>(char const *,char *)" (??$string_sprintf@PEAD@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDPEAD@Z) referenced in function "void __cdecl printType(struct emcl::astType *)" (?printType@@YAXPEAUastType@emcl@@@Z)
`
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<int>(char const *,int)" (??$string_sprintf@H@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDH@Z) referenced in function "void __cdecl printIntConstant(struct emcl::astIntConstant *)" (?printIntConstant@@YAXPEAUastIntConstant@emcl@@@Z)
`
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<unsigned int>(char const *,unsigned int)" (??$string_sprintf@I@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDI@Z) referenced in function "void __cdecl printUIntConstant(struct emcl::astUIntConstant *)" (?printUIntConstant@@YAXPEAUastUIntConstant@emcl@@@Z)
`
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<float>(char const *,float)" (??$string_sprintf@M@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDM@Z) referenced in function "void __cdecl printFloatConstant(struct emcl::astFloatConstant *)" (?printFloatConstant@@YAXPEAUastFloatConstant@emcl@@@Z)
`
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<double>(char const *,double)" (??$string_sprintf@N@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDN@Z) referenced in function "void __cdecl printDoubleConstant(struct emcl::astDoubleConstant *)" (?printDoubleConstant@@YAXPEAUastDoubleConstant@emcl@@@Z)
`
`
emc-language_debug.lib(emc-language.obj) : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl string_sprintf<>(char const *)" (??$string_sprintf@$$V@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBD@Z) referenced in function "void __cdecl printStatement(struct emcl::astStatement *)" (?printStatement@@YAXPEAUastStatement@emcl@@@Z)
`