Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ RUN(NAME test_c_interop_02 LABELS cpython llvm c
EXTRAFILES test_c_interop_02b.c)
RUN(NAME test_c_interop_03 LABELS llvm c
EXTRAFILES test_c_interop_03b.c)
RUN(NAME test_c_interop_04 LABELS llvm c
RUN(NAME test_c_interop_04 LABELS cpython llvm c
EXTRAFILES test_c_interop_04b.c)
RUN(NAME test_c_interop_05 LABELS llvm c
EXTRAFILES test_c_interop_05b.c)
Expand Down
6 changes: 5 additions & 1 deletion integration_tests/test_c_interop_04.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
from ltypes import ccall, f32, f64, i32, i64, CPtr, pointer, Pointer, p_c_pointer
from ltypes import (ccall, f32, f64, i32, i64, CPtr, pointer, Pointer,
p_c_pointer, empty_c_void_p)
from numpy import empty, int32

@ccall
def sum_pi32_i32(x: CPtr) -> i32:
pass

def test_c_callbacks():
xi32: i32[4]
xi32 = empty(4, dtype=int32)
sumi32: i32
xi32[0] = 3
xi32[1] = 4
xi32[2] = 5
xi32[3] = 6
print(xi32[0], xi32[1], xi32[2], xi32[3])
p: CPtr
p = empty_c_void_p()
p_c_pointer(pointer(xi32), p)
print(pointer(xi32), p)
sumi32 = sum_pi32_i32(p)
Expand Down
5 changes: 5 additions & 0 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3336,6 +3336,11 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
// with the type
tmp = nullptr;
return;
} else if (call_name == "empty_c_void_p") {
// TODO: check that `empty_c_void_p uses` has arguments that are compatible
// with the type
tmp = nullptr;
return;
} else if (call_name == "TypeVar") {
// Ignore TypeVar for now, we handle it based on the identifier itself
tmp = nullptr;
Expand Down
28 changes: 23 additions & 5 deletions src/runtime/ltypes/ltypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import platform
from typing import TypeVar

__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "c_ptr",
"overload", "ccall", "TypeVar", "pointer", "Pointer"]
# TODO: this does not seem to restrict other imports
__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "CPtr",
"overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer"]

# data-types

Expand Down Expand Up @@ -120,13 +121,15 @@ def convert_type_to_ctype(arg):
return ctypes.c_int64
elif arg == i32:
return ctypes.c_int32
elif arg == CPtr:
return ctypes.c_void_p
elif arg is None:
raise NotImplementedError("Type cannot be None")
elif isinstance(arg, Array):
type = convert_type_to_ctype(arg._type)
return ctypes.POINTER(type)
else:
raise NotImplementedError("Type not implemented")
raise NotImplementedError("Type %r not implemented" % arg)
def get_rtlib_dir():
current_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(current_dir, "..")
Expand Down Expand Up @@ -174,8 +177,23 @@ def ccall(f):
wrapped_f = CTypes(f)
return wrapped_f

def pointer(type_):
return type_
def pointer(x):
from numpy import ndarray
if isinstance(x, ndarray):
return ctypes.c_void_p(x.ctypes.data)
#return x.ctypes.data_as(ctypes.POINTER(ctypes.c_int32))
else:
type_ = x.annotations[0]
if type_ == i32:
return ctypes.pointer(ctypes.c_int32(x))
else:
raise Exception("Type not supported in pointer()")

def c_p_pointer(cptr, targettype):
return pointer(targettype)

def p_c_pointer(ptr, cptr):
cptr.value = ptr.value

def empty_c_void_p():
return ctypes.c_void_p()