Excel VBA,无法从DLL文件中查找DLL入口点

时间:2017-05-23 01:38:22

标签: c++ vba dll

我正在尝试使用Excel VBA访问和使用DLL文件中的函数的能力。

示例:

Private Declare Function funcName Lib _
"<filePath\File.dll>" _
(ByRef a As Double, ByRef b As Double) As Double

按照Mircosoft's tutorial关于如何创建DLL文件的说明,当我尝试构建项目时,为声明的3个函数引出3个警告(C4273):

'MathLibrary::Functions::Add': inconsistent dll linkage,
'MathLibrary::Functions::Multiply': inconsistent dll linkage,
'MathLibrary::Functions::AddMultiply': inconsistent dll linkage

当Excel中的VBA尝试从本教程访问创建的.dll文件时,会产生运行时错误(453):&#39;无法找到DLL入口点添加&# 34;路径\ file.dll&#34;

对于C \ C ++语言我是新手。 我花了6个多小时:

  • 尝试对香草教程进行调整
  • 重新开始
  • 谷歌搜索帮助和类似问题
  • 对VBA中的陈述进行调整

然而我从一个解决方案中感觉更远。

我在64位Windows上运行32位Excel。

非常感谢任何帮助:)

修改

代码文件(根据要求):

MathLibrary.cpp

// MathLibrary.cpp : Defines the exported functions for the DLL application.
// Compile by using: cl /EHsc /DMATHLIBRARY_EXPORTS /LD MathLibrary.cpp  

#include "stdafx.h"  
#include "MathLibrary.h"  

namespace MathLibrary
{
    double Functions::Add(double a, double b)
    {
        return a + b;
    }

    double Functions::Multiply(double a, double b)
    {
        return a * b;
    }

    double Functions::AddMultiply(double a, double b)
    {
        return a + (a * b);
    }
}

MathLibrary.h

// MathLibrary.h - Contains declaration of Function class  
#pragma once  

#ifdef MATHLIBRARY_EXPORTS  
#define MATHLIBRARY_API __declspec(dllexport)   
#else  
#define MATHLIBRARY_API __declspec(dllimport)   
#endif  

namespace MathLibrary
{
    // This class is exported from the MathLibrary.dll  
    class Functions
    {
    public:
        // Returns a + b  
        static MATHLIBRARY_API double Add(double a, double b);

        // Returns a * b  
        static MATHLIBRARY_API double Multiply(double a, double b);

        // Returns a + (a * b)  
        static MATHLIBRARY_API double AddMultiply(double a, double b);
    };
}

stdafx.h中

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// TODO: reference additional headers your program requires here

targetver.h

#pragma once

// Including SDKDDKVer.h defines the highest available Windows platform.

// If you wish to build your application for a previous Windows platform,
//     include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support 
//     before including SDKDDKVer.h.

#include <SDKDDKVer.h>

VBA模块

Private Declare Function Add Lib _
"c:\<Path>\MathLibrary.dll" _
(ByRef a As Double, ByRef b As Double) As Double

Sub useAddXL()
    MsgBox Add(1, 2)
End Sub

1 个答案:

答案 0 :(得分:1)

我将在解决方案中发布此内容,因为它不适合发表评论。

不一致的dll链接”警告:我从问题中复制了您的确切代码,因为此时 (可能会更改)在将来),并将其放置在新创建的 VStudio 2015 项目中:

  • 配置类型:动态库( .dll
  • 使用预编译的标题(虽然我通常不这样做)

如果我定义MATHLIBRARY_EXPORTS,项目编译没有警告

  • MathLibrary.cpp 文件#define MATHLIBRARY_EXPORTS之前 #include "MathLibrary.h"
  • 作为项目设置:在项目属性 - &gt;下添加它配置属性 - &gt; C / C ++ - &gt;预处理器 - &gt;预处理器定义(在其他宏旁边,以分号分隔(; ))

我唯一可以想象你在构建你的时候仍然会收到警告,因为你为错误的配置定义宏
示例:您正在为 Debug - x86 构建项目,但是您为 Release - x86 (或 Debug - x64 定义了宏>)。
你必须检查(最好选择所有平台所有配置,并且只定义宏一次),构建配置和设置配置匹配,如下图所示:

VStudio project settings

但无论如何,这个警告是良性的, .dll 仍然是构建的,并且导出了符号。

更进一步,在 VBA 模块中,您声明了函数名称​​ Add (plain)。 基于错误消息:

  

在“path \ file.dll”

中找不到DLL入口点添加

正如我在其中一条评论中指出的那样,由于[MSDN]: Decorated Names,我认为 Excel 无法导入 C ++ 样式导出> C ++ 名称修改)。当它搜索添加时,您的 .dll 会导出以下符号,如下面的( Dependency Walker )图像所示(您可以使用突出显示按钮并查看 Dependency Walker 如何 demangle 这些名称):

enter image description here

您应该从 Excel 导入的那些(乱码)名称,但我怀疑这是可能的。作为一种解决方法,您可以:

  • 删除 C ++ 功能(类和命名空间)并定义和导出3个简单函数
  • 编写3个 C 函数(3个方法的包装器),导出函数而不是方法

[SO]: Linker error when calling a C function from C++ code in different VS2010 project (@CristiFati's answer)包含所有详细信息(请注意extern "C"[MSDN]: Using extern to Specify Linkage)。