You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++跨DLL调用问题:封装求和DLL时编译错误求助

问题分析与解决方案

核心编译错误原因

LVadd = GetProcAddress(DLL18, "sumAB");报错的本质是:LVadd是你定义的普通函数,并非函数指针变量,C++不允许直接给函数名赋值。除此之外,代码还存在函数指针类型不匹配、DLL入口不规范、生命周期管理错误等问题,以下是完整修正方案:


步骤1:修正DLL18的入口函数(规范DLL结构)

DLL的合法入口是DllMain而非main,原代码中的main毫无意义,且sumAB;是无效语句,修正后代码如下:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "dll18.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

void sumAB(double in1, double in2, double *out1)
{
     *out1 = in1 + in2;
}

步骤2:修正DLL19的头文件(修复导出宏错误)

原DLL19头文件误用了dll18_EXPORTS宏,应该替换为自身的导出宏:

#pragma once

#ifdef dll19_EXPORTS
    #define dll19_API __declspec(dllexport)
#else
    #define dll19_API __declspec(dllimport)
#endif
extern "C" dll19_API void LVadd(double fromLV1, double fromLV2, double* toLV);

步骤3:修正DLL19的主文件(解决编译错误+实现正确调用)

关键修正点:

  1. 定义与sumAB完全匹配的函数指针类型
  2. 用全局变量管理DLL18的模块句柄,避免重复加载/卸载
  3. 在LVadd内部调用DLL18的sumAB函数
  4. 增加错误处理,避免空指针调用崩溃

修正后代码:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h> // 必须包含Windows.h才能使用LoadLibrary等API
#include "dll19.h"

// 定义匹配sumAB的函数指针:void返回、__cdecl调用约定(extern "C"默认)
typedef void(__cdecl *sumABFunc)(double in1, double in2, double* out1);

// 全局存储DLL18的模块句柄,进程加载时初始化,退出时释放
HMODULE g_hDLL18 = nullptr;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        // 进程加载DLL19时,加载依赖的DLL18
        g_hDLL18 = LoadLibraryA("DLL18.dll");
        break;
    case DLL_PROCESS_DETACH:
        // 进程退出时,释放DLL18
        if (g_hDLL18)
        {
            FreeLibrary(g_hDLL18);
            g_hDLL18 = nullptr;
        }
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

void LVadd(double fromLV1, double fromLV2, double* toLV)
{
    // 先判断DLL18是否加载成功
    if (!g_hDLL18)
    {
        *toLV = 0; // 加载失败时的默认处理
        return;
    }

    // 获取sumAB函数的地址
    sumABFunc sumAB = (sumABFunc)GetProcAddress(g_hDLL18, "sumAB");
    if (sumAB)
    {
        // 调用DLL18的sumAB完成求和
        sumAB(fromLV1, fromLV2, toLV);
    }
    else
    {
        *toLV = 0; // 获取函数失败时的默认处理
    }
}

额外说明

  • 函数指针的调用约定必须与原函数一致:extern "C"修饰的函数默认使用__cdecl,如果DLL18的sumAB指定了__stdcall,函数指针也需要同步修改。
  • 不要在DllMain中调用复杂逻辑,这里仅做DLL的加载/释放是安全的。
  • 确保DLL18.dll与DLL19.dll在同一目录,或者在系统可搜索的路径中,否则LoadLibrary会失败。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 10:05:55