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

如何通过宏配置用同一份代码编译DLL和静态库且无需客户端额外传宏

该需求完全可以实现,核心是调整头文件的宏判断逻辑,取消客户端侧Windows平台默认添加的__declspec(dllimport)标记,即可同时兼容静态库和DLL的引用场景,无需客户端额外传入编译宏。

第一步:修改hash.h宏定义

替换原有的宏逻辑为如下内容:

#ifndef HASHH
#define HASHH

// 编译库本身时的逻辑
#if defined(BUILD)
    #if defined(STATIC)
        // 静态库编译场景
        #define ADDAPI
        #define ADDCALL
        #define EXTERN extern
    #else
        // 动态库编译场景
        #define EXTERN
        #ifdef _WIN32
            #define ADDAPI __declspec(dllexport)
            #define ADDCALL __cdecl
        #else
            // 兼容非Windows平台的符号可见性配置
            #define ADDAPI __attribute__((visibility("default")))
            #define ADDCALL
        #endif
    #endif
// 客户端引用头文件时的逻辑
#else
    #define EXTERN extern
    #ifdef _WIN32
        // 客户端侧取消dllimport声明,同时兼容静态库、DLL两种链接方式
        #define ADDAPI
        #define ADDCALL __cdecl
    #else
        #define ADDAPI
        #define ADDCALL
    #endif
#endif

/*** The sha3-256 hash function.
@param buffer The buffer containing the data to be hashed.
@param length The length of the buffer.
@param digest The hash of the data in buffer.
*/
ADDAPI EXTERN int ADDCALL sha3_256(unsigned char* buf, unsigned long len, unsigned char* digest);

#endif

第二步:保留原有编译逻辑无需修改

原来的Windows平台编译命令可以直接复用,仅需对静态库编译命令做极小的严谨性调整:

  • 编译DLL:
gcc -c -D BUILD source\hash.c -o objects\hash.o
ld -s -shared objects\hash.o -o hash.dll
  • 编译静态库:
gcc -c -D BUILD -D STATIC source\hash.c -o objects\hash.o
ar rcs hash.lib objects\hash.o

补充说明:静态库编译命令新增了-D BUILD宏,和头文件的新逻辑匹配,原命令漏传该宏也能运行,补充后逻辑更规范。

可选进阶优化(保留DLL调用性能)

如果希望保留DLL场景下__declspec(dllimport)带来的调用性能提升,可以配合编译产物命名区分实现自动判断:

  1. 静态库编译后命名为hash_static.lib,DLL对应的导入库命名为hash.lib
  2. 在头文件客户端逻辑分支补充如下内容:
#ifdef _WIN32
    #if defined(HASH_USE_STATIC)
        #define ADDAPI
        // 自动链接静态库,无需客户端手动配置链接参数
        #pragma comment(lib, "hash_static.lib")
    #else
        #define ADDAPI __declspec(dllimport)
        // 自动链接DLL导入库,无需客户端手动配置链接参数
        #pragma comment(lib, "hash.lib")
    #endif
    #define ADDCALL __cdecl
#endif

需要使用静态库的客户端仅需定义HASH_USE_STATIC一个宏即可,相比原逻辑对用户更友好,也可以通过定制链接脚本进一步省略该宏定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 14:09:03