2008-09-15 17 views

Antwort

4

Leider haben Sie keinen VB6 verwenden können/VBA funktioniert als Callback direkt, da VB6 nur stdcall Funktionen generiert und nicht die cdecl Funktionen, die SQLite erwartet.

Sie müssen eine C-DLL schreiben, um die Aufrufe hin und her zu übernehmen oder SQLite neu kompilieren, um Ihre eigene benutzerdefinierte Erweiterung zu unterstützen.

nach dem DLL neu zu kompilieren, die Funktionen wie stdcall zu exportieren, können Sie eine Funktion mit dem folgenden Code registrieren:

'Create Function 
Public Declare Function sqlite3_create_function Lib "SQLiteVB.dll" (ByVal db As Long, ByVal zFunctionName As String, ByVal nArg As Long, ByVal eTextRep As Long, ByVal pApp As Long, ByVal xFunc As Long, ByVal xStep As Long, ByVal xFinal As Long) As Long 

'Gets a value 
Public Declare Function sqlite3_value_type Lib "SQLiteVB.dll" (ByVal arg As Long) As SQLiteDataTypes 'Gets the type 
Public Declare Function sqlite3_value_text_bstr Lib "SQLiteVB.dll" (ByVal arg As Long) As String  'Gets as String 
Public Declare Function sqlite3_value_int Lib "SQLiteVB.dll" (ByVal arg As Long) As Long    'Gets as Long 

'Sets the Function Result 
Public Declare Sub sqlite3_result_int Lib "SQLiteVB.dll" (ByVal context As Long, ByVal value As Long) 
Public Declare Sub sqlite3_result_error_code Lib "SQLiteVB.dll" (ByVal context As Long, ByVal value As Long) 

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long) 

Public Property Get ArgValue(ByVal argv As Long, ByVal index As Long) As Long 
    CopyMemory ArgValue, ByVal (argv + index * 4), 4 
End Property 

Public Sub FirstCharCallback(ByVal context As Long, ByVal argc As Long, ByVal argv As Long) 
    Dim arg1 As String 
    If argc >= 1 Then 
     arg1 = sqlite3_value_text_bstr(ArgValue(argv, 0)) 
     sqlite3_result_int context, AscW(arg1) 
    Else 
     sqlite3_result_error_code context, 666 
    End If 
End Sub 

Public Sub RegisterFirstChar(ByVal db As Long) 
    sqlite3_create_function db, "FirstChar", 1, 0, 0, AddressOf FirstCharCallback, 0, 0 
    'Example query: SELECT FirstChar(field) FROM Table 
End Sub 
+0

Ich habe es geschafft, eine stdcall freundliche Wrapper zu finden, die auch c arraya zu sicheren Arrays umwandelt usw. ., also Aufruf von Nicht-Callback-Funktionen funktioniert gut, es ist nur wie c-like Strukturen von einem Callback zurückgegeben, das ist mein nächstes Problem. Wie Sie gesagt haben, kann VBA sehr gut ersticken, bevor dieser Punkt erreicht wird. – gobansaor

+0

Ich habe es geschafft, den SQLite3VB-Wrapper zu modifizieren, um stdcall von bestimmten Funktionen zu unterstützen. Da meine Änderungen ziemlich kompliziert waren, habe ich nur den VB-Code veröffentlicht. Wenn Sie die Änderungen möchten, die ich an der SQLite-Quelle vorgenommen habe, posten Sie bitte Ihre E-Mail, damit ich sie senden kann. Vielleicht nachdem du auf deinem Blog posten kannst? – rpetrich

+0

Das ist exzellent, genau das was ich gesucht habe! Es wäre großartig, wenn Sie die SQLite-Quelländerungen an "tom at gobansaor.com" senden könnten. Ich bin dabei, verschiedene SQLite/ExcelVBA-Codebits zusammen zu ziehen, die ich dann auf meinem Blog veröffentlichen werde. Ich werde dafür sorgen, dass ich sie erwähnen werde, wenn ich es tue. – gobansaor