Mann kann mit dem Makro Operator direkt Funtkionen aufrufen, die mitgelinkt sind!
Code: Alles auswählen
if IsFunction("cFunc")
&(cFunc)(paramer liste) // ohne Codeblock
Das ist laut einem Gespräch auf einer der Devcons mit dem Alaska Team sogar ein schneller Aufruf, weil der direkt über die Funktionstabelle geht. Und der Linker mosert nicht wegen unbekannten Funktionen.
zu EXTERN:
Eine solche Deklaration macht ja nur Sinn, wenn ich schon vor dem Linken die Typen der Parameter kenne, also dass ich die Funktion unterstütze. Funktionen, welche ich erst während der Laufzeit identifiziere, muss ich mit DLLFUNKTION aufrufen:
Code: Alles auswählen
STATIC sApi:=NIL
LOCAL uRet
if IsNil(sApi)
sApi := DllPrepareCall( <dllname>, DLL_STDCALL, cFunc)
endif
uRet := DllExecuteCall(sApi, p1, p2, p3,......)
Das dürfte am Ende sich nicht viel von Ot4Xb unterscheiden (kennen den Code leider nicht), aber die technischen Rahmenbedingungen sind ja die selben. Ich weiß nicht, ob Ot4Xb die Typen der Parameter erkennen kann, dazu bräuchte es ja die LIB dazu. Ist im Normalfall wahrscheinlich auch kein Problem, weil ja alle Parameter auf C- Ebene 32bit Pointer sind. DIe aufgerufene Funktion weiß, was sich dahinter verbirgt: ein Integer oder ein Pointer auf eine Zeichenkette.
Man kann obige Funktion ja dahingehend erweitern, das man ein Array mit den Templates führt, um den 2. Aufruf zu beschhleunigen:
Code: Alles auswählen
FUNC DynCall(cDll, cFunc )
STATIC aTemplate := {}
LOCAL uRet
LOCAL nPos
if (nPos := ascan(aTemplate, {|a| a[1] == cFunc})) = 0
aadd( aTemplate, {cFunc, DllPrepareCall( <dllname>, DLL_STDCALL, cFunc)})
nPos := len(aTemplate)
endif
if pcount() = 3
uRet := DllExecuteCall(aTemplate[nPos,2], pValue(3))
elseif pcount() = 3
uRet := DllExecuteCall(aTemplate[nPos,2], pValue(3), pvlaue(4))
....
endif
return uRet