我想调用自定义函数Simil(LPCWSTR a, LPCWSTR b)
来计算Microsoft Access SQL(2019)中的Ratcliff/Obershelp string matching algorithm。该功能位于Simil.dll
中。以下是dllmain.cpp
文件,该文件定义了入口点,我使用Nuwen MinGW发行版进行了编译。
#ifdef __MINGW32__
#include <windows.h>
#endif
extern "C"
{
#include "simil.h"
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport) double Simil(LPCWSTR a, LPCWSTR b) {
return simil((const wchar_t*)a, (const wchar_t*)b);
}
我按如下所示将DLL加载到VBA中,并且在VBA本身中也能很好地工作。
Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" _
(ByVal lpLibFileName As String) As Long
Private Sub Init()
LoadLibrary(CurrentProject.Path & "/Simil.dll")
Debug.Print fnSimil(StrConv("TestABC", vbUnicode), StrConv("TestACB", vbUnicode)) ' 0,85..
Debug.Print fnSimil("TestABC", "TestACB") ' 0,85..
End Sub
但是,在Microsoft Access SQL中调用该函数时,由于成功调用并运行该函数(直至访问第一个参数的指令),程序由于访问冲突而崩溃。
Public Declare PtrSafe Function fnSimil _
Lib "Simil" Alias "Simil" _
(ByVal strOne As String, ByVal strTwo As String) As Double
Private Sub Update()
Me![Results].RowSource = "SELECT name from db ORDER BY fnSimil(db.name, ""Test"") DESC" ' crash!
End Sub
实际上,调试器告诉我,无论我如何更改上面的SQL查询,Simil
的第一个参数似乎总是地址0x0000000000000005
。据我所知,第二个参数也指向垃圾,但至少它是一个有效的地址。
如果进行32位构建,也要使函数WINAPI(__stdcall):
extern "C" double WINAPI Simil(LPCWSTR A, LPCWSTR B) { ... }