You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在VBA中导入自行编译的C++库DLL函数?附dumpbin导出信息

Calling Your C++ DLL Functions from VBA

Alright, let's break down how to get your compiled C++ DLL working with VBA, using the dumpbin output you shared. First, a quick note: your DLL exports mangled C++ function names (like ?Add@Functions@MathLibrary@@SANNN@Z), which means these are C++-style functions (likely part of a namespace or class). Here's what you need to do:

1. Understand Your Function Signatures & Calling Convention

From the mangled names, we can parse key details:

  • The Add function, for example, returns a double and takes two double parameters (the NN in the mangled name stands for double, and SAN points to the return type + calling convention).
  • The A in the mangled name tells us the function uses the __cdecl calling convention (VBA's default is __stdcall, so we'll need to account for this mismatch).

2. Declare the DLL Functions in VBA

You have two options here, depending on whether you can recompile your DLL or not.

Option 1: Use the Mangled Export Names (If You Can't Recompile)

Since your DLL already has mangled names, you'll need to reference those exact names in your VBA declarations. Open the VBA editor (press Alt+F11 in Excel/Office), insert a new module, and add this code:

' Replace the path with your actual DLL file path
Declare Function MathLib_Add Lib "C:\Path\To\HelloDLL.dll" _
    Alias "?Add@Functions@MathLibrary@@SANNN@Z" _
    (ByVal a As Double, ByVal b As Double) As Double Cdecl

Declare Function MathLib_AddMultiply Lib "C:\Path\To\HelloDLL.dll" _
    Alias "?AddMultiply@Functions@MathLibrary@@SANNN@Z" _
    (ByVal a As Double, ByVal b As Double) As Double Cdecl

Key notes here:

  • Lib: Specify the full path to your DLL (or just the filename if it's in a system/Office directory).
  • Alias: Must match the exact mangled name from dumpbin (case and symbols matter!).
  • Cdecl: Critical here—since your C++ function uses __cdecl, adding this ensures VBA uses the correct calling convention (omitting this will cause stack errors).
  • Parameter types: Double in VBA maps directly to C++'s double, and ByVal ensures we pass values correctly.

Option 2: Recompile the DLL with extern "C" (Cleaner Approach)

If you can recompile your C++ library, you can avoid mangled names entirely by using extern "C" to export functions in a C-compatible style. Modify your C++ code like this:

#include <cmath>

namespace MathLibrary {
    class Functions {
    public:
        // Export with C linkage to avoid name mangling
        extern "C" __declspec(dllexport) double __cdecl Add(double a, double b) {
            return a + b;
        }

        extern "C" __declspec(dllexport) double __cdecl AddMultiply(double a, double b) {
            return (a + b) * a;
        }
    };
}

After recompiling, your dumpbin output will show clean, unmangled names like Add and AddMultiply. Then your VBA declaration simplifies to:

Declare Function Add Lib "HelloDLL.dll" _
    (ByVal a As Double, ByVal b As Double) As Double Cdecl

Declare Function AddMultiply Lib "HelloDLL.dll" _
    (ByVal a As Double, ByVal b As Double) As Double Cdecl

3. Call the Functions in VBA

Once you've declared the functions, you can use them in any VBA procedure. For example:

Sub TestDLLFunctions()
    Dim addResult As Double
    Dim addMultiplyResult As Double
    
    addResult = MathLib_Add(2.5, 3.5) ' Or just Add() if you used Option 2
    addMultiplyResult = MathLib_AddMultiply(2.5, 3.5) ' Or AddMultiply()
    
    MsgBox "Add Result: " & addResult & vbCrLf & "AddMultiply Result: " & addMultiplyResult
End Sub

Critical Gotchas to Avoid

  • Bitness Match: Make sure your DLL's architecture matches your Office installation (64-bit DLL for 64-bit Office, 32-bit for 32-bit). Mismatches will throw "module not found" errors.
  • Calling Convention Consistency: If you switch your C++ function to __stdcall, remove the Cdecl keyword from your VBA declaration (VBA uses __stdcall by default).
  • Path Accuracy: Always test with the full DLL path first—relative paths can cause issues if the DLL isn't in a system-wide search directory.

内容的提问来源于stack exchange,提问作者Fabian Schneider

火山引擎 最新活动