在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效

Invalid memory address passed when calling custom DLL function in Microsoft Access SQL

本文关键字:内存 无效 地址 函数 DLL Access Microsoft SQL 自定义 调用      更新时间:2023-10-16

>我想调用一个自定义函数Simil(LPCWSTR a, LPCWSTR b),用于计算Microsoft Access SQL (2019(中的Ratcliff/Obershelp字符串匹配算法。该函数驻留在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);
}

我在 VBA 中加载 DLL 如下,它在 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。据我所知,第二个参数也指向垃圾,但至少它是一个有效的地址。

我找到了解决方法。我在 VBA 中使用了一个用户定义函数 (UDF(,我可以从 SQL 上下文中调用它。此函数需要驻留在模块中才能在 SQL 中使用。

Function fnSimilWrapper(a, b)
fnSimilWrapper = fnSimil(a, b)
End Function

如果执行 32 位构建,则还要创建函数 WINAPI (__stdcall(:

extern "C" double WINAPI Simil(LPCWSTR A, LPCWSTR B) { ... }