使用发布与调试配置在 DLL 中进行名称重组

问题描述 投票:0回答:1

我有一个在 Visual Studio 2022 中编译的简单 DLL 测试用例,目的是从 Excel VBA(64 位)调用它:

primefact.cpp:

#include "pch.h"
#include "primefact.h"
#define DllExport   __declspec( dllexport )

DllExport bool __stdcall isPrimeNumber(long long z)
{
    long long i;
    if (z < 2) return false;
    if (z == 2) return true;
    if (z % 2 == 0) return false;
    for (i = 3; i * i <= z; i += 2)
    {
        if (z % i == 0) return false;
    }
    return true;

primefact.h

#pragma once
__declspec(dllexport) bool isPrimeNumber(long long z);

VBA代码:

Declare PtrSafe Function isPrimeNumber Lib "C:\Users\theld\source\repos\PrimeFactors\x64\Debug\PrimeFactors.dll" (ByVal z As LongLong) As Boolean

Sub test()
    Dim z As LongLong
    Dim a As Boolean
    
    z = 11
    a = isPrimeNumber(z)
    MsgBox a
End Sub

在调试配置下编译时,VBA 可以成功调用 DLL。在发布配置中编译的相同代码会导致运行时错误 453,找不到 DLL 入口点。是的,我确实更改了“Declare”VBA 语句中的目录以指向 Release 子目录。

当我在两个 DLL 上运行 DUMPBIN 时,调试版本输出(除其他外):

      1    0 00011299 isPrimeNumber = @ILT+660(?isPrimeNumber@@YA_N_J@Z)

Release 版本输出:

     1    0 00001010 ?isPrimeNumber@@YA_N_J@Z = ?isPrimeNumber@@YA_N_J@Z (bool __cdecl isPrimeNumber(__int64))

很明显,Release 配置不会对函数导出进行破坏,而 Debug 则可以。

我尝试过包含模块定义文件(但没有):

LIBRARY PrimeFactors
EXPORTS
isPrimeNumber

包括(而不是)__declspec( dllexport ) 和/或 __stdcall 指令,而不影响 VBA 错误和 DUMPBIN 输出。我还尝试在各种选项中更改配置属性/C/C++/代码生成/运行时库,但没有效果。

excel vba dll
1个回答
0
投票

首先,响应 Hans Passant 的回复 - 是的,存在(或曾经)有问题,因为 Excel VBA 找不到 DLL 入口点。

其次,非常感谢 Hermann Baum,我正在关注的教程的作者(集成您自己的 DLL(64 位)) 使用 Visual Studio 2022 创建到 Excel VBA)。他能够重现我的问题,并找到解决方案。当您从调试模式切换到发布模式时,您必须再次告诉 Visual Studio 模块定义文件的名称(配置属性/链接器/输入/模块定义文件)。尽管 Microsoft 的文档另有说明,您仍然需要模块定义文件来让链接器分配分解名称(即 __declspec ( dllexport ) 是不够的)。

现在代码可以运行了!

© www.soinside.com 2019 - 2024. All rights reserved.