Как передать указатель массива на функцию в 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 это неверно:

  1. gep Метод получает коллекцию индексов, поэтому не уверен, что там делает тип.
  2. Приемник gep Метод должен быть указателем (или вектором-указателем), а получатель - массивом.

Но фундаментальная проблема здесь заключается в том, что вы пытаетесь получить адрес постоянной времени компиляции, то есть адрес чего-то, что никогда не выделяется в памяти.

Правильный способ сделать то, что вы пытаетесь сделать, это создать глобальную переменную, которая

  1. Инициализирован на ваш "привет мир" и
  2. Помечены как постоянные

Такой переменной присваивается адрес (указатель типа на массив i8) - и тогда вы можете использовать gep или же bitcast константные выражения, чтобы получить i8* и отправьте его в вашу функцию печати.

Например, попробуйте скомпилировать программу переменного тока со строковым литералом в LLVM IR, и вы увидите, что строковый литерал был помещен в такую ​​глобальную переменную.

Другие вопросы по тегам