DLL 的"good"调用约定是什么?
What is the "good" calling convention for a DLL?
我正在尝试编写一个可以从Excel VBA调用的DLL函数(C++(。当我尝试调用带有参数的函数时,我一直Run-time error '49': Bad DLL calling convention
。调用没有参数的函数没有问题。我相信我涵盖了大多数明显的陷阱(例如,我使用 > dumpbin /EXPORTS
验证了函数名称(,所以我真的一定错过了一些基本的东西。我在下面发布代码。
我在Windows 7和Windows 10上都收到相同的错误。我正在使用Visual Studio 2017和MS Excel 2007和2016(2007在7框中,2016在10框中(。我正在使用受本演练启发的__declspec
和extern "C"
语法
数学图书馆.h
#pragma once
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
extern "C" MATHLIBRARY_API int add_integers(int a, int b);
extern "C" MATHLIBRARY_API int get_integer();
数学图书馆.cpp
#include "stdafx.h"
#include "MathLibrary.h"
int add_integers(int a, int b)
{
return a + b;
}
int get_integer()
{
return 69;
}
VBA 模块函数和定义
Option Explicit
Declare Function add_integers Lib "..MathLibrary.dll" (ByVal x As Integer, ByVal y As Integer) As Integer
Declare Function get_integer Lib "..MathLibrary.dll" () As Integer
Public Function test()
Dim x As Integer
Dim y As Integer
Dim i As Integer
x = 42
y = 27
' this returns 69
i = get_integer()
' this throws Run-time error 49
i = add_integers(x, y)
End Function
感謝 Hans Passant 為我指出了正確的方向。如果使用__stdcall
定义函数,则它可以工作。
数学图书馆.h
#pragma once
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
extern "C" MATHLIBRARY_API int __stdcall add_integers(int a, int b);
extern "C" MATHLIBRARY_API int __stdcall get_integer();
数学图书馆.cpp
/* MathLibrary.cpp : Defines the exported functions for the DLL application. */
#include "stdafx.h"
#include "MathLibrary.h"
int __stdcall add_integers(int a, int b)
{
return a + b;
}
int __stdcall get_integer()
{
return 69;
}
这些函数导出为"_add_integers@8"和"_get_integer@0",我从 VBA 中这样调用它们。
Option Explicit
Declare Function add_integers Lib "..MathLibrary.dll" Alias "_add_integers@8" (ByVal x As Integer, ByVal y As Integer) As Integer
Declare Function get_integer Lib "..MathLibrary.dll" Alias "_get_integer@0" () As Integer
Public Function test()
Dim x As Integer
Dim y As Integer
Dim i As Integer
x = 42
y = 27
' this returns 69
i = get_integer()
' this also returns 69
i = add_integers(x, y)
End Function
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- "std::unique_XXX"命名约定背后的基本原理是什么?
- DLL 的"good"调用约定是什么?
- 合并函数参数的适当命名约定是什么?
- 返回布尔值的函数的命名约定是什么
- 当我需要添加一个无用的返回语句时,C++约定是什么
- c++setter编码约定.输入变量名称应该是什么
- 这个标题的命名约定指的是什么
- WinRT中字段的正确命名约定是什么
- 导出函数的默认调用约定是什么(VS2008)
- Windows RT在ARM上的本机代码调用约定是什么?
- visual studio中静态成员函数的默认调用约定是什么?
- C++ lambda 函数的默认调用约定是什么?
- 命名约定-在C++标识符中使用下划线的规则是什么