// Automatically generated C++ file on Thu Apr 9 13:05:26 2026 // // To build with Digital Mars C++ Compiler: // // dmc -mn -WD -o exampledll.cpp kernel32.lib #include union uData { bool b; char c; unsigned char uc; short s; unsigned short us; int i; unsigned int ui; float f; double d; long long int i64; unsigned long long int ui64; char *str; unsigned char *bytes; }; // int DllMain() must exist and return 1 for a process to load the .DLL // See https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain for more // information. int __stdcall DllMain(void *module, unsigned int reason, void *reserved) { return 1; } // #undef pin names lest they collide with names in any header file(s) you might // include. #undef IN1 #undef IN2 #undef IN3 #undef OUT1 #undef OUT2 // this is data for each schematic instance, persistent across evaluation // function calls struct InstData { double inData[3]; // may or may not be needed -- see evaluation function double outData[2]; // may or may not be needed -- see evaluation function }; // original functions operate on global data -- you'll need to rework them to // operate on per-instance data or passed value pointers // void init(int out_int[], int out_int_num); // void Set_Data(double in[], int in_num); // void Get_Data(double out[], int out_num); // void Sim(void); // your Sim() function needs to operate on passed arrays like this: void Sim(double inArray[], int szInArray, double outArray[], int szOutArray) { // do calculations } extern "C" __declspec(dllexport) void exampledll( InstData **opaque, double t, uData *data) { double IN1 = data[0].d; // input double IN2 = data[1].d; // input double IN3 = data[2].d; // input double &OUT1 = data[3].d; // output double &OUT2 = data[4].d; // output InstData *inst = *opaque; if (!*opaque) { inst = *opaque = (InstData *)calloc(sizeof(InstData), 1); // this is where you'd put initialization, i.e., your init() call after // reworking to add a per-instance pointer parameter } // here is where your Set_Data(), Sim(), and Get_Data() calls would go... // Set_Data() and Get_Data() probably aren't needed -- they copy data into // global variables which is not a good idea. use per-instance data if // persistence across Sim() calls is needed. // // we simply need to pass arrays of inputs and outputs into Sim() for the // calculations and point Sim() to the two arrays.... // we can make the arrays local variables: double inVals[3]; double outVals[2]; int nbrInVals = sizeof(inVals) / sizeof(inVals[0]); int nbrOutVals = sizeof(outVals) / sizeof(outVals[0]); // OR make them per-instance data: // double *inVals = inst->inData; // double *outVals = inst->outData; // int nbrInVals = sizeof(inst->inData) / sizeof(inst->inData[0]); // int nbrOutVals = sizeof(inst->outData) / sizeof(inst->outData[0]); // the order of uData values in data is easily broken when editing the // schematic C-Block. to be safe, let's populate the arrays using the // template-generated uData names (be sure to regenerate the uData definitions // if you edit the schematic C-Block!): inVals[0] = IN1; inVals[1] = IN2; inVals[2] = IN3; // then we call your calculation routine (Sim()) Sim(inVals, nbrInVals, outVals, nbrOutVals); // finally, we set the output ports to the calculated output values. again, // we don't assume that the uData elements are in a specific order and use the // uData names: OUT1 = outVals[0]; OUT2 = outVals[1]; } extern "C" __declspec(dllexport) void Destroy(InstData *inst) { free(inst); }