The example shows what needs to be done in the user SystemC code portable for different simulators.
NC_SYSTEMC is a macro defined by Cadence SystemC. It is automatically defined if you are using Cadence Incisive SystemC (known also as NC-SC). If you are using OSCI (see the part under #else) you must implement sc_main(). Otherwise, you don't need to have sc_main(), if you are running NC-SC.
UVM_ML_MODULE_EXPORT is defined in UVM-ML in the header file $UVM_ML_HOME/ml/adapters/uvm_sc/uvm_ml.h
It enables procedural instantiation of a topmost SC module (in this example, sc_top) from a UVM test.
ml_synchronize() is defined in UVM SV ML adapter. It can be helpful if you are using OSCI SystemC. The commercial versions of SystemC automatically synchronize between SystemVerilog and SystemC kernels. However, for OSCI, you need to do it manually. That means, you need to do an operation described belwo in order to keep SysytemC and SystemVerilog time matching and SystemC processes running.
Currently there are two ways. Ml_synchronize() allows you to synchronize proactively, like in this example, at the edge of a sufficiently fast SV clock. Upon each call to ml-synchronize() SC kernel advances to the current SV time, giving a chance to SC processes to run (if they are waiting for some time delay).
Alternatively, you could use an asynchronous synchronization - UVM-ML automatically synchronizes times every time a TLM transaction is passed from SV to SC. But the latter mechanism suits only if your SC code is executed at zero time upon arrival of a SV transaction.
Hope this helps,