我有一个程序在我使用C ++运行时工作正常但是,当我从我的LLVM IR代码调用它时它不起作用。
extern "C" DLLEXPORT double *DOT(double A[3][3], double B[3][3]) {
std::cout << A[0][0] << std::endl;
...
}
declare [3 x double] @DOT([3 x [3 x double]], [3 x [3 x double]])
...
%a1 = load [3 x [3 x double]], [3 x [3 x double]]* %a
%b2 = load [3 x [3 x double]], [3 x [3 x double]]* %b
%calltmp = call [3 x double] @DOT([3 x [3 x double]] %a1, [3 x [3 x double]] %b2)
我没有包含完整的程序以节省空间,但是,如果它有用,只需询问,我会更新问题。
[1] 3086 segmentation fault ./built
我使用以下命令编译代码:
clang++ library/library.cpp out.ll -o built
这有效:
std::cout << A[0] << std::endl; // 0x1
这不是:
std::cout << A[0][0] << std::endl;
答案 0 :(得分:2)
您使用错误的签名声明了您的函数:
首先,你的函数返回一个指向double的指针,而不是一个双精度数组。这很清楚,因为C ++代码确实将double *
称为返回类型。
不太明显的问题是你的参数类型是“指向double数组的指针”,而不是“double to array”。这是因为C和C ++不支持数组类型的函数参数,但是仍然很容易地接受参数列表中的数组类型的语法,但只是将它视为声明指针。因此,double A[3][3]
在参数列表中(并且只在那里)只是一种更令人困惑的方式来编写double (*A)[3]
。
总之,你的声明应该是:
declare double* @DOT([3 x double]*, [3 x double]*)
因此,您还应该更改您的调用代码,使用正确类型的指针调用@DOT
。