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

C++共享库未导出extern "C"函数问题求助

解决extern "C"函数未导出的问题

1. 确认TEST_API宏的定义逻辑

你提到TEST_API包含导入导出声明,必须保证编译DLL项目时,这个宏被正确设置为导出。比如DLL_Macro.h里的宏逻辑应该是这样的:

#ifdef BUILD_DLL
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif

如果编译时没定义BUILD_DLL,哪怕类的函数能导出,extern "C"的函数也可能因为宏被当成导入而不导出。

2. 调整extern "C"的写法

把所有C风格函数塞进一个extern "C"块里,避免重复声明的同时,确保编译器正确识别C链接规则:

extern "C" {
    __declspec(dllexport) void* Create(int x) {
        return (void*) new Attempt(x);
    };

    __declspec(dllexport) int AttemptAdd(Attempt * a, int y) {
        return a->adding(y);
    };
}

3. 检查编译与链接选项

  • 确认项目是**动态链接库(DLL)**类型,不是静态库。
  • 如果用Visual Studio,右键项目→属性→链接器→输入,若有模块定义(.def)文件,要手动添加导出项:
    EXPORTS
    Create
    AttemptAdd
    
    用def文件可以强制导出函数,绕开宏定义的潜在问题。

4. 分离函数声明与实现

把extern "C"函数的声明放在头文件,实现移到cpp文件里,避免头文件重复编译导致的导出异常:

头文件代码

#pragma once
#include "DLL_Macro.h"

class TEST_API Attempt {
    int x;
public:
    Attempt(int x);
    int adding(int y);
};

extern "C" {
    __declspec(dllexport) void* Create(int x);
    __declspec(dllexport) int AttemptAdd(Attempt * a, int y);
}

cpp文件代码

#include "你的头文件名.h"

Attempt::Attempt(int x) : x(x) {}
int Attempt::adding(int y) { return x + y; }

void* Create(int x) {
    return (void*) new Attempt(x);
}

int AttemptAdd(Attempt * a, int y) {
    return a->adding(y);
}

修改后重新编译,用DependenciesGUI查看导出表,就能看到无名字修饰的Create和AttemptAdd了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:15:22