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

如何通过LLVM将数组正确传递给C函数?解决调用崩溃问题

LLVM传递数组给C函数崩溃的原因及解决方法

问题场景

尝试创建一个包含两个64位元素的数组,存储到局部变量后加载并传递给C函数。调用接收指针参数的C函数时程序崩溃,但调用接收单个64位值的C函数时可正常打印数组首个元素。

原始LLVM字节码

define i32 @main() {
  %1 = alloca [2 x i64], align 8
  store [2 x i64] [i64 1, i64 10], [2 x i64]* %1, align 4
  %2 = load [2 x i64], [2 x i64]* %1, align 4
  call void @printType([2 x i64] %2)
  ret i32 0
}

崩溃的C函数

void printType(int64_t* parts) {
   printf("%ld\n", parts[0]);
}

可正常运行的C函数

void printType(int64_t parts) {
    printf("%ld\n", parts);
}

核心问题

你忽略了LLVM数组类型与C数组参数的传递规则差异:

  • 在LLVM中,[2 x i64]是完整的数组值类型,当你通过call void @printType([2 x i64] %2)调用函数时,是把整个数组的两个64位值按值传递到函数栈中。
  • 但你的C函数printType(int64_t* parts)期望接收的是指针类型(数组的首地址),此时栈中的两个64位值会被C函数当作内存指针解析,这显然是无效地址,访问时必然触发崩溃。
  • 第二个C函数能正常运行只是巧合:它接收单个64位值,刚好读取了栈中传递的数组第一个元素的值,但这并不是正确的数组传递方式。

解决方案

需要传递数组的指针而非数组本身的值,同时确保LLVM中的指针类型与C函数参数类型匹配。修改后的LLVM字节码如下:

define i32 @main() {
  %1 = alloca [2 x i64], align 8
  store [2 x i64] [i64 1, i64 10], [2 x i64]* %1, align 8
  ; 将数组指针转换为i64*类型,匹配C函数的int64_t*参数
  %arr_ptr = bitcast [2 x i64]* %1 to i64*
  call void @printType(i64* %arr_ptr)
  ret i32 0
}

C函数保持原指针版本即可:

#include <stdio.h>
void printType(int64_t* parts) {
   printf("%ld\n", parts[0]);
}

说明

  • bitcast指令用于转换指针类型:LLVM中[2 x i64]*(数组指针)和i64*(元素指针)的内存地址相同,但类型不同,显式转换后才能匹配C函数的参数类型。
  • 直接传递数组指针给C函数,函数就能正确访问数组的首元素,避免无效地址访问导致的崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:12:26