代码之家  ›  专栏  ›  技术社区  ›  nemo

DLL的“好”调用约定是什么?

  •  1
  • nemo  · 技术社区  · 7 年前

    我正在尝试编写一个DLL函数(用C++),我可以从Excel VBA调用它。我一直在 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" 语法灵感来自 this walkthrough

    MathLibrary。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();
    

    MathLibrary。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
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   nemo    7 年前

    幸亏 Hans Passant 给我指指点点 right direction 。如果使用定义函数 __stdcall 它起作用了。

    MathLibrary。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();
    

    MathLibrary。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;
    }
    

    函数导出为“\u add”_integers@8“和”\u获取_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