Danilo wrote:What do you want to do? Write object-oriented classes with PB, that get called from Microsoft VisualC++?
Yes. And I already made it. But the problem with register ecx when transmitting string in a procedure or if enabled threadsafe.
Danilo wrote:Wouldn't it make sense to use a object-oriented programming language to write object-oriented classes and member functions?
Complete compatibility is required with classes VisualC++ 8, otherwise will not work. Not suitable other compilers C++, for example, MinGV, Borland C++ Builder, etc. The code compiles but does not work correctly.
And using PureBasic, you can create a working code.

But the problem with register ecx.
For example, VisualC++ code.
Code: Select all
#include "Vsm.hpp"
class DSOURDEVICE : public IDSIMMODEL
{
public:
INT isdigital (CHAR *pinname);
VOID setup (IINSTANCE *inst, IDSIMCKT *dsim);
VOID runctrl (RUNMODES mode);
VOID actuate (REALTIME time, ACTIVESTATE newstate);
BOOL indicate (REALTIME time, ACTIVEDATA *data);
VOID simulate (ABSTIME time, DSIMMODES mode);
VOID callback (ABSTIME time, EVENTID eventid);
private:
IINSTANCE *inst;
IDSIMCKT *ckt;
IDSIMPIN *Pin1;
IDSIMPIN *Pin2;
IDSIMPIN *Pin3;
IDSIMPIN *Pin4;
BOOL state;
};
extern "C" IDSIMMODEL __declspec(dllexport) * createdsimmodel (CHAR *device, ILICENCESERVER *ils)
{
if (ils->authorize(0x80808081))
return new DSOURDEVICE;
else
return NULL;
}
extern "C" VOID __declspec(dllexport) deletedsimmodel (IDSIMMODEL *model)
{
delete (DSOURDEVICE *)model;
}
INT DSOURDEVICE::isdigital (CHAR *pinname)
{
return 1;
}
VOID DSOURDEVICE::setup (IINSTANCE *instance, IDSIMCKT *dsimckt)
{
inst = instance;
ckt = dsimckt;
Pin1 = instance->getdsimpin("Pin1", true);
Pin2 = instance->getdsimpin("Pin2", true);
Pin3 = instance->getdsimpin("Pin3", true);
Pin4 = instance->getdsimpin("Pin4", true);
Pin3->setstate(SHI);
Pin4->setstate(SHI);
ckt->setcallback(1000000000000, this, 0x25);
}
VOID DSOURDEVICE::runctrl (RUNMODES mode)
{
}
VOID DSOURDEVICE::actuate (REALTIME time, ACTIVESTATE newstate)
{
}
BOOL DSOURDEVICE::indicate (REALTIME time, ACTIVEDATA *data)
{
return TRUE;
}
VOID DSOURDEVICE::simulate (ABSTIME time, DSIMMODES mode)
{
/* Pin3->setstate(time, 1, Pin1->istate());
Pin4->setstate(time, 1, Pin2->istate());*/
}
VOID DSOURDEVICE::callback (ABSTIME time, EVENTID eventid)
{
if (eventid == 0x25)
{
if (ishigh(Pin3->istate()))
Pin3->setstate(time, 1, SLO);
else
Pin3->setstate(time, 1, SHI);
ckt->setcallback(time + 1000000000000, this, 0x25);
}
}
The translated code to PureBasic.
Code: Select all
XIncludeFile "vsm.pbi"
Structure ClassParam
*vt ;pointer to virtual table as first entry
; Приватные переменные класса.
*inst.IINSTANCE
*ckt.IDSIMCKT
*Pin1.IDSIMPIN
*Pin2.IDSIMPIN
*Pin3.IDSIMPIN
*Pin4.IDSIMPIN
State.b
EndStructure
EnableExplicit
EnableASM
Declare ModelNEW()
ProcedureCDLL createdsimmodel(device.s, *ils.ILICENCESERVER)
Protected *Result=0
If *ils\Authorize($80808081)
*Result=ModelNEW()
EndIf
ProcedureReturn *Result
EndProcedure
ProcedureCDLL deletedsimmodel(*model.IDSIMMODEL)
If *model
FreeMemory(*model)
EndIf
EndProcedure
Procedure isdigital(*PinName)
Protected *This.ClassParam
MOV *This, ecx
ProcedureReturn 1 ; В компоненте все выводы цифровые.
EndProcedure
Procedure setup(*instance.IINSTANCE, *dsimckt.IDSIMCKT)
Protected *This.ClassParam
MOV *This, ecx
*This\inst = *instance ; Сохраняем указатели на объекты.
*This\ckt = *dsimckt
; Сохраняем указатели на объекты выводов модели.
*This\Pin1 = *instance\getdsimpin("Pin1", #True)
*This\Pin2 = *instance\getdsimpin("Pin2", #True)
*This\Pin3 = *instance\getdsimpin("Pin3", #True)
*This\Pin4 = *instance\getdsimpin("Pin4", #True)
*This\Pin3\setstate3(#SHI)
*This\Pin4\setstate3(#SHI)
*This\ckt\setcallback(1000000000000, *This, $25)
EndProcedure
Procedure runctrl(mode.RUNMODES)
Protected *This.ClassParam
MOV *This, ecx
EndProcedure
Procedure actuate(time.REALTIME, newstate.ACTIVESTATE)
Protected *This.ClassParam
MOV *This, ecx
EndProcedure
Procedure indicate(time.REALTIME, *aData.ACTIVEDATA)
Protected *This.ClassParam
MOV *This, ecx
ProcedureReturn #True
EndProcedure
Procedure simulate(time.ABSTIME, mode.DSIMMODES)
Protected *This.ClassParam
MOV *This, ecx
;*This\Pin3\setstate2(time, 1, *This\Pin1\istate())
;*This\Pin4\setstate2(time, 1, *This\Pin2\istate())
EndProcedure
Procedure callback(time.ABSTIME, eventid.EVENTID)
Protected *This.ClassParam
MOV *This, ecx
If eventid = $25
If ishigh(*This\Pin3\istate())
*This\Pin3\setstate2(time, 1, #SLO)
Else
*This\Pin3\setstate2(time, 1, #SHI)
EndIf
*This\ckt\setcallback(time + 1000000000000, *This, $25)
EndIf
EndProcedure
Procedure ModelNEW() ; Создание объекта.
Protected *this.ClassParam=0
*this = AllocateMemory(SizeOf(ClassParam))
If *this
*this\vt = ?ClassFunct
EndIf
ProcedureReturn *this
EndProcedure
DataSection
ClassFunct:
Data.i @isdigital()
Data.i @setup()
Data.i @runctrl()
Data.i @actuate()
Data.i @indicate()
Data.i @simulate()
Data.i @callback()
EndDataSection
For conversion of calls from stdcall to thiscall, in interfaces, use
this macro.