【发布时间】:2019-07-18 16:27:53
【问题描述】:
尝试从 VBA (MS Access) 调用 C++ DLL 并不断收到“错误的 dll 调用约定”错误,以及 MS Access 崩溃。
这是我试图调用的 C++ API 函数:
_IMPORT HRESULT _CONVENTION PCRSNewTrip (Trip *pTripID);
“行程”定义为:
typedef long Trip;
来自 API 标头:
#if defined (__BORLANDC__)
#define _IMPORT __declspec( dllimport )
#define _CONVENTION __stdcall
#elif defined (_MSC_VER)
#define _IMPORT _declspec( dllimport )
#define _CONVENTION _cdecl
#endif
这里有一些关于函数的信息: PCRSNewTrip() 在传入的指针参数 (tripID) 中放置新行程的句柄。返回代码与所有其他 DLL 函数(用于错误处理)相同。
这是我调用该函数的最新尝试:
Public Declare Function PCRSNewTrip Lib "C:\xxx\pcrsrv32.dll" Alias "_PCRSNewTrip" (ByRef myTripPtr As Long) As Long
Private Sub NewTrip_Click()
Dim myTrip As Long
Dim myTripPtr As Long
myTripPtr = VarPtr(myTrip)
myTrip = PCRSNewTrip(myTripPtr)
EndSub
我收到“错误的 DLL 调用约定”错误。
【问题讨论】:
-
Win32 VBA 仅支持
STDCALL。_CONVENTION是什么? -
另外
ByRef已经让你传递一个指针,所以你传递一个指向指针的指针。但这不应该导致这个错误。 -
来自 API 头文件:#if defined (BORLANDC) #define _IMPORT __declspec( dllimport ) #define _CONVENTION __stdcall #elif defined (_MSC_VER) #define _IMPORT _declspec( dllimport ) #define _CONVENTION _cdecl #endif
-
我不认为 C++ 的
long与 VBA 的Long含义相同。我认为您追求的是 VBA 的LongPtr。 Reference -
另外,
_CONVENTION显然因编译器而异。我不是 C++ 专家,但如果您使用 Microsoft 编译器进行编译,您会得到_cdecl,这是不受支持的。它必须是__stdcall贯穿始终。