hab mich gerade mit der Plugin-Schnittstelle vom Amibroker (Börsensoftware von http://www.amibroker.com) beschäftigt.
Ich will ein AFL-Plugin schreiben, und zumindest alles was ich brauche funktioniert erstmal.
Leider habe ich aber nicht das "SiteInterface" zum laufen bekommen welches so in C/C++ definiert ist:
Code: Alles auswählen
struct SiteInterface
{
int nStructSize;
int (*GetArraySize) (void);
float * (*GetStockArray)( int nType );
AmiVar (*GetVariable) ( const char *pszName );
void (*SetVariable) ( const char *pszName, AmiVar newValue );
AmiVar (*CallFunction) ( const char *szName, int nNumArgs, AmiVar *ArgsTable );
AmiVar (*AllocArrayResult) (void);
void * (*Alloc) (unsigned int nSize);
void (*Free) (void *pMemory);
DATE_TIME_INT* (*GetDateTimeArray) (void); // new in 5.30
};
Code: Alles auswählen
Structure SiteInterface
nStructSize.l
*GetArraySize.pGetArraySize
*GetStockArray.pGetStockArray
*GetVariable.pGetVariable
*SetVariable.pSetVariable
*mCallFunction.pCallFunction
*AllocArrayResult.pAllocArrayResult
*Alloc.pAlloc
*Free.pFree
*GetDateTimeArray.pGetDateTimeArray
EndStructure
Funktion zuzugreifen. z.B. selbst ein "einfaches" GetVariable funktioniert einfach nicht, und wird mit Speicherfehlern vom Amibroker quittiert.
Hier mal ein Code eines AFL-Plugins, welches für Amibroker die Funktion "BTS_Test" zur Verfügung stellt.
Hier ist sicherlich "überflüssiges" aus Vergangenen Tests drin, und man könnte es sicherlich ordentlicher schreiben,
aber grundlegend funktionierts erstmal - bis leider auf das "SiteInterface"
Code: Alles auswählen
#PLUGIN_VERSION = 10000
#PLUGIN_NAME = "Test"
#VENDOR_NAME = "VoSs2o0o"
#NumberofFunctions = 1
Enumeration
#PLUGIN_TYPE_AFL = 1
#PLUGIN_TYPE_DATA
#PLUGIN_TYPE_AFL_AND_DATA
#PLUGIN_TYPE_OPTIMIZER
EndEnumeration
Enumeration
#VAR_NONE
#VAR_FLOAT
#VAR_ARRAY
#VAR_STRING
#VAR_DIS
EndEnumeration
Structure AmiVar
type.l
StructureUnion
val.f
*mArray.f[0]
*string.STRING
*disp.l
EndStructureUnion
EndStructure
Structure PluginInfo
nStructSize.l ;// this is SizeOf( struct PluginInfo )
nType.l ; // plug-in type currently 1 - indicator is the only one supported
nVersion.l ; // plug-in version coded to int as MAJOR*10000 + MINOR * 100 + RELEASE
nIDCode.l ;// ID code used to uniquely identify the data feed (set it to zero for AFL plugins)
szNname.s{64} ;// long name of plug-in displayed in the Plugin dialog
szVendor.s{64} ;;// name of the plug-in vendor
nCertificate.l ;// certificate code - set it to zero for private plug-ins
nMinAmiVersion.l ;// minimum required AmiBroker version (should be >= 380000 -> AmiBroker 3.8)
EndStructure
Prototype.l pGetArraySize()
Prototype.f pGetStockArray(nType.l)
Prototype.l pGetVariable(*pszName.STRING)
Prototype.l pSetVariable(*pszName.s, *newValue.AmiVar)
Prototype.l pCallFunction(szName.s, nNumArgs.l, *ArgsTable.AmiVar)
Prototype.l pAllocArrayResult()
Prototype.l pAlloc(nSize.l)
Prototype.l pFree(*pMemory)
Prototype.q pGetDateTimeArray()
Structure SiteInterface
nStructSize.l
*GetArraySize.pGetArraySize
*GetStockArray.pGetStockArray
*GetVariable.pGetVariable
*SetVariable.pSetVariable
*mCallFunction.pCallFunction
*AllocArrayResult.pAllocArrayResult
*Alloc.pAlloc
*Free.pFree
*GetDateTimeArray.pGetDateTimeArray
EndStructure
Structure FARRAY
f.f[0]
EndStructure
Structure AMIARRAY
ami.AmiVar[0]
EndStructure
Prototype.l pFunction(NumArgs.l, Array *ArgsTable.Amivar(1))
Structure FunDesc
Function.l
ArrayQty.b
StringQty.b
FloatQty.b
DefaultQty.b
*DefaultValues.FARRAY
EndStructure
Structure FunctionTag
Name.STRING
Descript.FunDesc
EndStructure
ProcedureDLL AttachProcess(Instanz.l)
Global Dim FunctionTable.FunctionTag(#NumberofFunctions )
Global Dim *myArgs.Amivar(0)
Global *gpinterface.SiteInterface
Global *erg.AmiVar
*erg.AmiVar = AllocateMemory(1000)
Global strParam1.STRING
EndProcedure
ProcedureCDLL.l GetPluginInfo(*pinfo.Plugininfo)
*pinfo\nStructSize = SizeOf(PluginInfo)
*pinfo\nType = #PLUGIN_TYPE_AFL
*pinfo\nVersion = #PLUGIN_VERSION
*pinfo\nIDCode = 0
*pinfo\szNname = #PLUGIN_NAME
*pinfo\szVendor = #VENDOR_NAME
*pinfo\nCertificate = 0
*pinfo\nMinAmiVersion = 530000
ProcedureReturn 1
EndProcedure
ProcedureCDLL.l Init()
ProcedureReturn 1
EndProcedure
ProcedureCDLL.l Release()
ProcedureReturn 1
EndProcedure
ProcedureCDLL.l SetSiteInterface(*pinterface.SiteInterface)
*gpinterface = *pinterface
ProcedureReturn 1
EndProcedure
ProcedureC.l BTS_Test(NumArgs.l, *pArgsTable.AmiVar)
MessageRequester("NumArgs", Str(NumArgs.l))
If NumArgs.l > 0
ReDim *myArgs.Amivar(NumArgs.l - 1)
For i=0 To NumArgs.l - 1
*myArgs(i) = *pArgsTable + (i*SizeOf(AmiVar))
MessageRequester("CurrentArg", Str(i))
MessageRequester("type", Str(*myArgs(i)\type))
MessageRequester("val", Str(*myArgs(i)\val))
Next
EndIf
;######################################
ProcedureReturn 1
EndProcedure
ProcedureCDLL.l GetFunctionTable(*ppFunctionTable)
FunctionTable(0)\Name\s = "BTS_Test"
FunctionTable(0)\Descript\Function = @BTS_Test()
FunctionTable(0)\Descript\ArrayQty = 0
FunctionTable(0)\Descript\StringQty = 0
FunctionTable(0)\Descript\FloatQty = 0
FunctionTable(0)\Descript\DefaultQty = 3
*FunctionTable_DefaultValues.FARRAY = AllocateMemory(FunctionTable(0)\Descript\DefaultQty)
*FunctionTable_DefaultValues\f[0] = 1
*FunctionTable_DefaultValues\f[1] = 2
*FunctionTable_DefaultValues\f[2] = 5
PokeL(@FunctionTable(0)\Descript\DefaultValues, *FunctionTable_DefaultValues)
PokeL(*ppFunctionTable, @FunctionTable(0))
ProcedureReturn #NumberofFunctions
EndProcedure
Ich hoffe das jemand weiterhelfen kann bezüglich des "siteinterfaces"
PS: Das Amibroker "ADK" gibts auf der Downloadseite von Amibroker.com, und enthält eine Anleitung und
C/C++ Beispielcodes wie ein solch ein Plugin zu schreiben ist.