C++ Excel VBA,无法从 DLL 文件中找到 DLL 入口点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44124452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Excel VBA, Can't Find DLL Entry Point from a DLL file
提问by carl13
I am attempting to use Excel VBA's ability to access and use functions from DLL files.
我正在尝试使用 Excel VBA 访问和使用 DLL 文件中的函数的能力。
example:
例子:
Private Declare Function funcName Lib _
"<filePath\File.dll>" _
(ByRef a As Double, ByRef b As Double) As Double
Following the instructions from Mircosoft's tutorialon how to create a DLL file, leads to 3 warnings (C4273) when I try to build the project, for the 3 functions declared:
按照Mircosoft关于如何创建 DLL 文件的教程中的说明,当我尝试构建项目时,对于声明的 3 个函数会导致 3 个警告 ( C4273):
'MathLibrary::Functions::Add': inconsistent dll linkage,
'MathLibrary::Functions::Multiply': inconsistent dll linkage,
'MathLibrary::Functions::AddMultiply': inconsistent dll linkage
When the VBA in Excel tries to access the created .dll file from this tutorial, it produces a runtime error (453): 'Can't find DLL entry point Add in "path\file.dll".
当 Excel 中的 VBA 尝试访问本教程中创建的 .dll 文件时,它会产生运行时错误 ( 453):“找不到 DLL 入口点添加到“path\file.dll”中。
I am a novice when it comes to the C\C++ language. I have spent over 6 hours of:
我是 C\C++ 语言的新手。我花了超过 6 个小时的时间:
- trying to make tweaks to the vanilla tutorial
- starting over
- googling for help, and similar issues
- making tweaks to the statements within VBA
- 尝试对原版教程进行调整
- 从头开始
- 谷歌搜索帮助和类似问题
- 对 VBA 中的语句进行调整
And yet I feel further from a solution.
然而,我觉得离解决方案更远了。
I am running 32-bit Excel on 64-bit Windows.
我在 64 位 Windows 上运行 32 位 Excel。
Any help would be much appreciated :)
任何帮助将非常感激 :)
Edit
编辑
Code Files (as requested):
代码文件(根据要求):
MathLibrary.cpp
数学库.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
数学图书馆.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 Module
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
采纳答案by CristiFati
I'm going to post this in a solution, as it doesn't fit in an comment.
我将在解决方案中发布它,因为它不适合评论。
The "inconsistent dll linkage" warning: I copied your exact codefrom the question as it is at this point(it might change in the future), and placed it in a newly created VStudio 2015project:
该“不一致的DLL联动”警告:我复制你的确切的代码从这个问题,因为它是在这一点(它可能在未来改变),并把它放在一个新创建的VStudio 2015年的项目:
- Configuration type: Dynamic Library (.dll)
- Using precompiled headers (although, I usually don't do it)
- 配置类型:动态库(.dll)
- 使用预编译头文件(虽然我通常不这样做)
The project compiled with no warnings, if I define MATHLIBRARY_EXPORTSeither:
如果我定义MATHLIBRARY_EXPORTS,则该项目编译时没有警告:
- In the MathLibrary.cppfile
#define MATHLIBRARY_EXPORTS
(before#include "MathLibrary.h"
) - As a project setting: adding it under Project Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions(next to other macros, separated by semicolons (;))
- 在MathLibrary.cpp文件中
#define MATHLIBRARY_EXPORTS
(之前#include "MathLibrary.h"
) - 作为项目设置:在项目属性 -> 配置属性 -> C/C++ -> 预处理器 -> 预处理器定义下添加它(在其他宏旁边,用分号(;)分隔)
The only thing that I can imagine for you to still get the warning when building yours, is because you are defining the macro for the wrong configuration.
Example: you are building your project for Debug - x86, but you define the macro for Release - x86(or Debug - x64).
You must check (it would be better select All Platfromsand All Configurations, and only define the macro once) that build configurations and settings configurations match, like in the image below:
我能想象的唯一一件事是,您在构建时仍然收到警告,因为您正在为错误的配置定义宏。
示例:您正在为Debug - x86构建项目,但您为Release - x86(或Debug - x64)定义了宏。
您必须检查(最好选择All Platfroms和All Configurations,并且只定义一次宏)构建配置和设置配置匹配,如下图所示:
But anyway, this warning is benign, the .dllis still built, and the symbols exported.
但无论如何,这个警告是良性的,.dll仍然被构建,并且符号被导出。
Going further, in your VBAmodule you declare the function name Add(plain). Based on the error message:
更进一步,在您的VBA模块中,您声明了函数名称Add(plain)。根据错误消息:
Can't find DLL entry point Addin "path\file.dll"
Can't find DLL entry point Addin "path\file.dll"
as I specified on one of my comments, I don't think that Excelis able to import C++style exports because of [MS.Docs]: Decorated Names(C++name mangling). While it searches for Add, your .dllexports the following symbols as shown in the (Dependency Walker) image below (you can play with the highlighted button and see how Dependency Walkeris able to demanglethose names):
正如我在其中一条评论中指出的那样,我认为Excel无法导入C++样式导出,因为[MS.Docs]: Decorated Names( C++name mangling)。当它搜索Add 时,您的.dll 会导出以下符号,如下面的 ( Dependency Walker) 图像所示(您可以使用突出显示的按钮并查看Dependency Walker如何对这些名称进行解码):
Those (gibberish) names you should import from Excel, but I doubt that's possible. As a workaround you could either:
您应该从Excel导入的那些(胡言乱语)名称,但我怀疑这是可能的。作为一种解决方法,您可以:
- Drop the C++features (the class and the namespace) and define and export 3 simple functions
- Write 3 Cfunctions (wrappers over the 3 methods), and export the functions not the methods
- 删除C++特性(类和命名空间)并定义和导出 3 个简单函数
- 编写 3 个C函数(封装了 3 个方法),并导出函数而不是方法
[SO]: Linker error when calling a C function from C++ code in different VS2010 project (@CristiFati's answer)contains all the details (pay attention on extern "C"
: [MS.Docs]: extern (C++)).
[SO]:从不同 VS2010 项目中的 C++ 代码调用 C 函数时的链接器错误(@CristiFati 的回答)包含所有细节(注意extern "C"
:[MS.Docs]: extern (C++))。