Код: Выделить всё
# 0/main.py
from dataclasses import dataclass
@dataclass
class Point:
x: float
def addOne(p: Point) -> Point:
return Point(p.x + 1.0)
p1 = Point(1.0)
print(p1)
p2 = addOne(p1)
print(p2)
Код: Выделить всё
(0) $ python main.py
Point(x=1.0)
Point(x=2.0)
Код: Выделить всё
# 1/main.py
from libexample import Point, makePoint, printPoint, addOne
p1 = Point(1.0) # or makePoint(1.0)
printPoint(p1)
p2 = addOne(p1)
printPoint(p2)
Код: Выделить всё
// 1/libexample.chpl
// -- types used by exported functions need to be exported
// -- cannot export records, so we use extern
// export record Point {
// var x: real(64);
// }
extern {
typedef struct {
double x;
} Point;
}
// -- altenatively
// require "point.h";
// --
// $ cat point.h
// #ifndef POINT_H
// #define POINT_H
// typedef struct {
// double x;
// } Point;
// #endif
extern record Point {
var x: real(64);
}
export proc makePoint(x: real): Point {
var p: Point = new Point(x);
return p;
}
export proc printPoint(in p: Point) {
writeln("Point(", p.x, ")");
}
export proc addOne(in p: Point): Point {
return new Point(p.x + 1.0);
}
Код: Выделить всё
// 1/main.chpl
use libexample;
var p1 = makePoint(1.0);
printPoint(p1);
var p2 = addOne(p1);
printPoint(p2);
Код: Выделить всё
(1) $ chpl main.chpl
(1) $ ./main
Point(1.0)
Point(2.0)
Код: Выделить всё
(1) $ chpl --library --library-python libexample.chpl
Error compiling Cython file:
------------------------------------------------------------
...
from libc.stdint cimport *
from chplrt cimport *
cdef extern from "libexample.h":
void chpl__init_libexample(int64_t _ln, int32_t _fn);
Point makePoint(double x);
^
------------------------------------------------------------
./chpl_libexample.pxd:6:1: 'Point' is not a type identifier
# ... and more of such errors
Рабочий (но утомительный и неподдерживаемый) обходной путь — написать оболочки Python, чтобы распаковать все в базовые типы для вызова Chapel и переупаковать возвращаемые значения.
Код: Выделить всё
# 2/main.py
from dataclasses import dataclass
@dataclass
class Point:
x: float
def addOne(p: Point):
from libexample import addOne as addOne_chpl
return Point(addOne_chpl(p.x))
p1 = Point(1.0)
print(p1)
p2 = addOne(p1)
print(p2)
Код: Выделить всё
// 2/libexample.chpl
export proc addOne(p_x: real(64)): real(64) {
return p_x + 1.0;
}
Код: Выделить всё
(2) $ chpl --library --library-python libexample.chpl
(2) $ python main.py
Point(x=1.0)
Point(x=2.0)
Я также изучил модуль Python и увидел, что он позволяет определять пользовательские типы (https://github.com/chapel-lang/chapel/b ... mType.chpl).
Насколько я понимаю Понимаете, вы можете вызывать код Python из Chapel (возможно, с настраиваемыми структурами), но я хочу сделать наоборот: вызвать код Chapel из Python с настраиваемыми структурами. Структуры могут быть сначала определены либо в Python, либо в Chapel (хотя определение их сначала в Chapel кажется более разумным)
Существует ли в настоящее время «хороший» способ сделать это? В идеале структура должна быть определена только один раз, без необходимости использования специально написанных TypeConverter и тому подобного (которые на практике дублируют код). Спасибо за помощь!
Подробнее здесь: https://stackoverflow.com/questions/798 ... n-dataclas
Мобильная версия