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

可选动态库技术问询:Linux/跨平台实现与代码问题排查

关于可选动态库的跨平台实现疑问(结合Intel ITT API场景)

我在做可执行文件性能分析时使用Intel VTune性能分析器,了解到ITT API库可用于启停性能分析,核心函数为__itt_resume()和__itt_pause()。该库是可选动态库:未加载ITT运行时库时,这些函数会自动变为空操作(noop)。

我的疑问(先聚焦Linux平台)

  • 进程是启动时检查依赖动态库是否加载,还是运行时调用库中符号(或首个符号)时才检查(即懒初始化)?我明确Windows平台是启动时检查,会弹出“找不到XXX.dll”的提示,但不确定Linux的行为。另外我的测试示例中,即使some_process.c未定义目标符号,编译执行也完全正常。
  • 如何在Linux平台实现这种可选动态库机制?我查看ITT的代码后发现关键宏定义如下,它通过函数指针包裹调用逻辑,指针为NULL时直接做空操作:
#define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)
  • 如何跨平台(Windows、Mac、Linux)实现该机制?

我的测试示例(运行不符合预期)

我编写了最简测试代码,但结果不符合预期:加载库时未调用my_api_hello_impl(),未链接库时访问extern符号api_hello_ptr也未崩溃。

示例代码

my_api.c

#include "my_api.h"
#include <stdio.h>

void(*api_hello_ptr)();

void api_hello_impl()
{
    printf("Hello\n");
}

__attribute__((constructor))
static void init()
{
    printf("linked\n");
    api_hello_ptr = api_hello_impl;
}

my_api.h

#pragma once

extern void(*api_hello_ptr)();

inline void api_hello() { if(api_hello_ptr) api_hello_ptr(); }

some_process.c

#include "my_api.h"

int main()
{
    // 未链接时应为空操作
    api_hello();
}

Makefile

# my_api未链接到some_process
some_process: some_process.c my_api.h
    $(CC) -o $@ $<

my_api.so: my_api.c my_api.h
    $(CC) -shared -fPIC -o $@ $<

test_linked: some_process my_api.so
    LD_PRELOAD="$(shell pwd)/my_api.so" ./some_process

test_unlinked: some_process my_api.so
    ./some_process

.PHONY: test_linked test_unlinked

运行输出

$ make test_linked
LD_PRELOAD="/tmp/tmp.EkrQbILrNg/my_api.so" ./some_process
linked
$ make test_unlinked                                                                                               
./some_process

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:15:52