Как передать указатель массива на функцию в LLVM / llvmpy?
Я использую llvmpy
(попытаться) сгенерировать ИК код. Тем не менее, я застрял с помощью printf
и массив int8
,
Ниже приводится выдержка из того, что вызывает у меня проблемы:
# Defining the print function.
# -----
fntype = Type.function(Type.void(), [Type.pointer(Type.int(8))])
myprint = module.add_function(fntype, 'print')
cb = CBuilder(myprint)
x = cb.printf("%s\n", cb.args[0])
cb.ret()
cb.close()
# Creating the string.
# -----
chartype = Type.int(8)
chars = [Constant.int(chartype, ord(c)) for c in "Hello World!"]
string = Constant.array(chartype, chars)
ptr = string.gep([Constant.int(Type.int(8)), 0])
# Calling the print function.
# -----
cfn = exe.get_ctype_function(module.get_function_named('print'),
None, ct.c_char_p)
cfn(ptr)
Когда я запускаю этот код, я получаю
ctypes.ArgumentError: аргумент 1: неправильный тип
Что я делаю неправильно? Я чувствую, что мое использование .gep()
виноват, но я не уверен, каким образом. Или есть что-то еще, чего я не понимаю?
Кроме того, есть ли способ получить ожидаемый тип из функции?
1 ответ
Да, ваше использование gep
это неверно:
gep
Метод получает коллекцию индексов, поэтому не уверен, что там делает тип.- Приемник
gep
Метод должен быть указателем (или вектором-указателем), а получатель - массивом.
Но фундаментальная проблема здесь заключается в том, что вы пытаетесь получить адрес постоянной времени компиляции, то есть адрес чего-то, что никогда не выделяется в памяти.
Правильный способ сделать то, что вы пытаетесь сделать, это создать глобальную переменную, которая
- Инициализирован на ваш "привет мир" и
- Помечены как постоянные
Такой переменной присваивается адрес (указатель типа на массив i8) - и тогда вы можете использовать gep
или же bitcast
константные выражения, чтобы получить i8*
и отправьте его в вашу функцию печати.
Например, попробуйте скомпилировать программу переменного тока со строковым литералом в LLVM IR, и вы увидите, что строковый литерал был помещен в такую глобальную переменную.