vba - 运行时错误 49,Excel/VBA 的 D 语言 DLL 中的错误 DLL 调用约定 - 我错过了什么?
问题描述
我正在尝试从 Excel 中的 VBA 获得最简单的 D 语言 DLL。我正在使用 Visual D。首先,我使用以下代码从https://wiki.dlang.org/Win32_DLLs_in_D复制了样板示例,即带有 C 接口的 DLL :
module DDLL;
import core.sys.windows.windows;
import core.sys.windows.dll;
__gshared HINSTANCE g_hInst;
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
g_hInst = hInstance;
dll_process_attach( hInstance, true );
break;
case DLL_PROCESS_DETACH:
dll_process_detach( hInstance, true );
break;
case DLL_THREAD_ATTACH:
dll_thread_attach( true, true );
break;
case DLL_THREAD_DETACH:
dll_thread_detach( true, true );
break;
default:
}
return true;
}
我试图从 VBA 调用的 D 应用程序代码是这样的:
module myfns;
export double testdd(double a, double b) { return a + b + 0; }
export int testi(int x) {return 42 + x ; }
export int testii(int a, int b) { return a + b + 0; }
VBA代码是:
Option Explicit
Declare Function testdd Lib "C:\Users\vvkozlov\sources\DDLL\Win32\Debug\DDLL.dll" _
Alias "_D5myfns6testddFddZd" (ByVal x As Double, ByVal y As Double) As Double
Declare Function testi Lib "C:\Users\vvkozlov\sources\DDLL\Win32\Debug\DDLL.dll" _
Alias "_D5myfns5testiFiZi" (ByVal x As Long) As Long
Declare Function testii Lib "C:\Users\vvkozlov\sources\DDLL\Win32\Debug\DDLL.dll" _
Alias "_D5myfns6testiiFiiZi" (ByVal x As Long, ByVal y As Long) As Long
Public Sub test()
Dim x As Long: x = 42000
Debug.Print "two doubles: " & testdd(84#, -42#)
Debug.Print "one long: " & testi(x)
Debug.Print "two longs: " & testii(x, -x)
End Sub
请注意,我进去并从生成的 DLL 中找出了损坏的名称。
testdd(两个双精度)示例按预期工作,但两个 int 示例都导致
Runtime Error 49, Bad DLL calling convention
在 VBA 中。乍一看,参数声明似乎很好——Long
在 VBA 方面,int
在 D 中。
为什么double
示例在int
失败时有效?
解决方案
Adam D Ruppe 的建议是正确的。D 应用程序代码现在看起来像
module myfns;
import std.conv;
extern(Windows) export double testdd(double a, double b) { return a + b + 0; }
extern(Windows) export int testi(int x) {return 42 + x ; }
extern(Windows) export int testii(int a, int b) { return a + b + 0; }
它还具有至少简化名称修饰的令人愉快的副作用(不,从 VBA 代码中删除别名不起作用)。
VBA 现在看起来像
Option Explicit
Declare Function testdd Lib "C:\Users\vvkozlov\sources\DDLL\Win32\Debug\DDLL.dll" _
Alias "_testdd@16" (ByVal x As Double, ByVal y As Double) As Double
Declare Function testi Lib "C:\Users\vvkozlov\sources\DDLL\Win32\Debug\DDLL.dll" _
Alias "_testi@4" (ByVal x As Long) As Long
Declare Function testii Lib "C:\Users\vvkozlov\sources\DDLL\Win32\Debug\DDLL.dll" _
Alias "_testii@8" (ByVal x As Long, ByVal y As Long) As Long
现在开始BSTR
,然后也许SAFEARRAY
。没有Variant
。
推荐阅读
- python - openAI gym TypeError:无法解压不可迭代的NoneType对象
- javascript - 在 JavaScript 中运行函数后如何回到全局范围?
- visual-studio - 新的 Visual Studio 安装,测试未在测试资源管理器中运行
- dataframe - Pyspark fillna 具有来自另一个数据帧的值
- reactjs - React 告诉我,我不能在 contextAPI 的“Provider”函数中使用钩子
- sql - 从每个 id 具有特定值的表中选择行
- c - 如何将函数的返回值分配给变量
- c# - 以编程方式构建 - 未从程序集中加载“TransformTemplates”任务
- php - 使用 PHP 在 JSON 中搜索值
- typescript - 当某些参数是通用的或匿名的时键入 compose