The C++ entry code in Simplix unitmain.cpp and USR usr.cpp robots may seem a wee bit ridiculous, so here is an attempt to make it more clear (from Jean-Philippe):
Yes, the robot interface scheme may appear a bit strange ... I admit. When I enhanced it at the beginning of SD, it was in order it becomes simpler. But keeping TORCS compatibility actually blurs things.
Anyway, it is actually simple, once you know it:
this C interface can have the following forms (uppercase keywords are the ones used as the parameters of the "ROBOT_MODULE" cmake macro) :
"LEGACY_MIN" = the minimal TORCS interface (number of slots = 10 in modInfo):
extern "C" int <name>(tModInfo modInfo[10]);
"LEGACY" = the standard TORCS interface (number of slots = 10 in modInfo):
extern "C" int <name>(tModInfo modInfo[10]);
extern "C" int <name>Shut();
"WELCOME" = the standard SD interface (unlimited number of slots in modInfo):
extern "C" int moduleWelcome(const tModWelcomeIn* welcomeIn, tModWelcomeOut* welcomeOut)
extern "C" int moduleInitialize(tModInfo *ModInfo);
extern "C" int moduleTerminate();
the robot DLL can display the WELCOME form and another one at the same time (compatible with TORCS and SD as the same time). That's why you can read "INTERFACE LEGACY WELCOME" in your CMakeLists.txt.
Under Windows, things are a bit more complicated in the build system because you need to declare the functions your DLL exports, and for this, the old ".def file scheme" was kept (we could well use the more up-to-date declspec(dllexport) / declspec(import) scheme, right in the function declarations). This .def file is generated by our "ROBOT_MODULE" cmake macro (actually the "GENERATE_ROBOT_DEF_FILE" macro called by this one : have a look in cmake/macros.cmake), based on the declared interface form (in the CMakeLists.txt).
You can also look at the GfModInitialize function in tgf/modinfo.cpp, and you'll quickly understand how the different interface forms are detected at run-time and which one have priority on which other.
So ... why does some function like "usr_ls1" have to appear in the C interface of the usr DLL? Only for TORCS compatibility. Because USR is now a "schismatic" robot, just as Simplix, copying the DLL into another driver folder with a different name also implies it displays at least a "<copy name>" interface function. Otherwise TORCS would not load it. It is useless for SD, which only looks at the functions of the "WELCOME" form.