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

使用boost import_alias加载DLL函数时触发Access Violation异常

DLL函数调用访问违例问题排查

问题背景

尝试调用DLL中的construct函数,相关代码及异常信息如下:

DLL API定义

#pragma once

#include <stdint.h>
#include <stdbool.h>

#if defined _MSC_VER || defined __MINGW32__
    #ifdef __cplusplus
        #define API extern "C" __declspec(dllexport)
    #else
        #define API __declspec(dllexport)
    #endif
#else
    #ifdef __cplusplus
        #define API extern "C" __attribute__((visibility("default")))
    #else
        #define API __attribute__((visibility("default")))
    #endif
#endif


API void* construct(const char* initString);

Boost加载调用代码

#include <boost/dll/import.hpp>
#include <boost/function.hpp>
#include <boost/filesystem.hpp>
#include <iostream>


typedef void* (ConstructT)(const char*);

int main() {
    boost::function<ConstructT> constructFunc = boost::dll::import_alias<ConstructT>(
        "TestPluginDll.dll",
        "construct",
        boost::dll::load_mode::append_decorations | boost::dll::load_mode::load_with_altered_search_path
    );
    
    std::string initArg = "hello";
    void* pluginInstance = constructFunc(initArg.c_str());
    std::cout << pluginInstance << std::endl;
}

DLL实现代码

#include <plugin_interface.hpp>
#include <iostream>
#include <nlohmann/json.hpp>


class MyPlugin {
public:
    MyPlugin() {}
};


extern "C" API void* construct(const char* initString) {
    MyPlugin* plugin = new MyPlugin();
    return static_cast<void*>(plugin);
}

异常信息

Exception has occurred: W32/0xC0000005
Unhandled exception at 0x00007FF77B713633 in tmp.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

异常触发在Boost的import.hpp代码段:

// Compilation error at this point means that imported function
        // was called with unmatching parameters.
        //
        // Example:
        // auto f = dll::import_symbol<void(int)>("function", "lib.so");
        // f("Hello");  // error: invalid conversion from 'const char*' to 'int'
        // f(1, 2);     // error: too many arguments to function
        // f();         // error: too few arguments to function
        template <class... Args>
        inline auto operator()(Args&&... args) const
            -> decltype( (*f_)(static_cast<Args&&>(args)...) )
        {
            return (*f_)(static_cast<Args&&>(args)...);
        }

疑问:std::string.c_str()返回const char*,与函数参数类型匹配,为何触发异常?

问题原因分析

访问违例地址0xFFFFFFFFFFFFFFFF通常表示函数指针无效(未正确加载到目标函数),而非参数类型不匹配,可能的诱因包括:

  • Boost加载函数使用错误:import_alias用于加载通过BOOST_DLL_ALIAS定义的别名符号,而当前DLL直接导出函数本身,不适用该接口;
  • DLL路径错误:程序无法找到目标DLL,导致加载的模块句柄无效;
  • 编译架构不兼容:DLL与调用端程序的32/64位编译架构不一致;
  • 调用约定不匹配:DLL和调用端的函数调用约定(如cdecl/stdcall)未保持一致。

解决方案

1. 替换Boost加载接口

将boost::dll::import_alias改为boost::dll::import_symbol,适配直接导出的函数:

boost::function<ConstructT> constructFunc = boost::dll::import_symbol<ConstructT>(
    "TestPluginDll.dll",
    "construct",
    boost::dll::load_mode::append_decorations | boost::dll::load_mode::load_with_altered_search_path
);

2. 确保DLL路径正确

  • 将DLL放到exe同目录下;
  • 或使用绝对路径加载,避免路径搜索问题:
    boost::filesystem::path dll_path = boost::filesystem::current_path() / "TestPluginDll.dll";
    auto constructFunc = boost::dll::import_symbol<ConstructT>(
        dll_path,
        "construct",
        boost::dll::load_mode::append_decorations | boost::dll::load_mode::load_with_altered_search_path
    );
    

3. 统一编译架构

确保DLL和调用端程序使用相同的编译架构(均为32位或均为64位)。

4. 明确调用约定

若DLL修改了默认调用约定,需在类型别名和函数定义中统一指定:

// 调用端类型别名添加调用约定
typedef void* (__cdecl ConstructT)(const char*);

// DLL函数实现同步指定
extern "C" API __cdecl void* construct(const char* initString) {
    MyPlugin* plugin = new MyPlugin();
    return static_cast<void*>(plugin);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:22:38