2008-09-15 18 views

Répondre

4

Malheureusement, vous ne pouvez pas utiliser un VB6/La fonction VBA en tant que rappel directement en tant que VB6 génère uniquement des fonctions stdcall plutôt que les fonctions cdecl attendues par SQLite.

Vous devrez écrire un dll C pour transmettre les appels par procuration et recompiler SQLite pour prendre en charge votre propre extension personnalisée.

Après recompiler votre dll pour exporter les fonctions stdcall, vous pouvez enregistrer une fonction avec le code suivant:

'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

J'ai réussi à trouver un stdcall emballage convivial qui convertit également c Arraya à des réseaux de sécurité, etc. ., donc l'appel des fonctions de non-callback fonctionne bien, c'est juste comment gérer les structures de type c renvoyées par un callback, c'est mon prochain problème. Comme vous l'avez dit, VBA pourrait très bien s'étouffer avant que ce point ne soit atteint. – gobansaor

+0

J'ai réussi à modifier l'encapsuleur SQLite3VB pour supporter stdcall depuis certaines fonctions. Comme mes changements étaient assez impliqués, j'ai seulement posté le code VB. Si vous souhaitez que les modifications apportées à la source SQLite, s'il vous plaît envoyer votre e-mail afin que je puisse envoyer. Peut-être après que vous pouvez poster sur votre blog? – rpetrich

+0

C'est excellent, exactement ce que je cherchais! Ce serait génial si vous pouviez envoyer les changements de source SQLite à "tom at gobansaor.com". Je suis en train de rassembler divers morceaux de code SQLite/ExcelVBA que je publierai ensuite sur mon blog, je ferai en sorte de vous donner une mention quand je le ferai. – gobansaor