Как получить доступ к строкам из C в GraalVM? - PullRequest
1 голос
/ 08 октября 2019

Как получить доступ к строкам из C в GraalVM? Я приложил пример в Ada, где экспортируется функция Hello .

test.ads

with Ada.Text_IO;

with Interfaces.C;
with Interfaces.C.Strings;

package Test is

    package C renames Interfaces.C;

    function Hello return C.Strings.chars_ptr
        is (C.Strings.New_String ("abcdef"))
        with Export => True, Convention => C, External_Name => "hello";

end Test;

HelloGraal.scala

object HelloGraal {
  val polyglot: Context = Context.newBuilder()
    .allowAllAccess(true)
    .option("llvm.libraries", "./gnat-llvm/llvm-interface/lib/rts-native/adalib/libgnat.dylib")
    .build()

  def loadBcFile(file: File): Value = {
    val source = Source.newBuilder("llvm", file).build()
    polyglot.eval(source)
  }
  val test: Value = loadBcFile(new File("./ada/test.bc"))

  val hello = test.getMember("hello")

  def main(args: Array[String]): Unit = {
    println(hello.execute())
  }
}

Ответы [ 2 ]

3 голосов
/ 09 октября 2019

Я не очень хорошо знаю Аду, но я могу дать ответ для C. Я надеюсь, что кто-то знающий в Аде может "перевести" это;)

В битовом коде LLVM нет явного string type, есть просто i8*, и не каждый i8* обязательно является строкой, он также может быть просто произвольным указателем. Из-за этого вам нужно выполнить преобразование вручную.

Существует две функции API для преобразования строк "C" в значения строк "polyglot": polyglot_from_string преобразует строку с нулем в конце и polyglot_from_string_nпреобразует строку заданной длины.

Эти функции объявлены в polyglot.hgraalvm/jre/languages/llvm/include).

2 голосов
/ 08 октября 2019

Теоретически, класс Value из org.graalvm.polyglot предоставляет методы, которые позволяют запрашивать его тип, а также преобразовывать его в данный тип. В этом случае вы хотите использовать Value#asString(), поэтому в вашем примере

hello.execute().asString()

На самом деле это зависит от того, что интерпретатор LLVM возвращает вам и поддерживает ли он asString. Это может быть просто байтовый массив, который вы можете прочитать побайтно, используя Value#getArrayElement. Это может быть указатель на память вне кучи (что никогда не произойдет в управляемом режиме LLVM), которую вы можете прочитать, используя Value#asNativePointer.

Ответ Роланда дает более подробное описание.

...