Skip to content

Adds support for str type to ccall #674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 22, 2022
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
13 changes: 13 additions & 0 deletions integration_tests/test_c_interop_02.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def f_i16_i16(x: i16) -> i16:
def f_i8_i8(x: i8) -> i8:
pass

@ccall
def f_str_i32(x: str) -> i32:
pass

def test_c_callbacks():
xf64: f64
xf64 = 3.3
Expand All @@ -49,4 +53,13 @@ def test_c_callbacks():
xi8 = 3
assert f_i8_i8(xi8) == 4

assert f_str_i32("Hello World!") == 12
assert f_str_i32("abc") == 3
assert f_str_i32("a") == 1
assert f_str_i32("") == 0
x: str = "Hello World!"
assert f_str_i32(x) == 12
x = "abc"
assert f_str_i32(x) == 3

test_c_callbacks()
6 changes: 6 additions & 0 deletions integration_tests/test_c_interop_02b.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <string.h>

#include "test_c_interop_02b.h"

double f_f64_f64(double x) {
Expand All @@ -23,3 +25,7 @@ int16_t f_i16_i16(int16_t x) {
int8_t f_i8_i8(int8_t x) {
return x+1;
}

int32_t f_str_i32(char *x) {
return strlen(x);
}
1 change: 1 addition & 0 deletions integration_tests/test_c_interop_02b.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ int64_t f_i64_i64(int64_t x);
int32_t f_i32_i32(int32_t x);
int16_t f_i16_i16(int16_t x);
int8_t f_i8_i8 (int8_t x);
int32_t f_str_i32(char *x);


#endif // TEST_C_INTEROP_02B
4 changes: 3 additions & 1 deletion src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
std::string dims = convert_dims_c(t->n_dims, t->m_dims);
sub = format_type_c(dims, "bool", v.m_name, use_ref, dummy);
} else if (ASRUtils::is_character(*v.m_type)) {
// TODO
ASR::Character_t *t = ASR::down_cast<ASR::Character_t>(v.m_type);
std::string dims = convert_dims_c(t->n_dims, t->m_dims);
sub = format_type_c(dims, "char *", v.m_name, use_ref, dummy);
} else if (ASR::is_a<ASR::Derived_t>(*v.m_type)) {
std::string indent(indentation_level*indentation_spaces, ' ');
ASR::Derived_t *t = ASR::down_cast<ASR::Derived_t>(v.m_type);
Expand Down
10 changes: 9 additions & 1 deletion src/runtime/ltypes/ltypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ def convert_type_to_ctype(arg):
return ctypes.c_int8
elif arg == CPtr:
return ctypes.c_void_p
elif arg == str:
return ctypes.c_char_p
elif arg is None:
raise NotImplementedError("Type cannot be None")
elif isinstance(arg, Array):
Expand Down Expand Up @@ -176,7 +178,13 @@ def get_crtlib_path():
def __call__(self, *args, **kwargs):
if len(kwargs) > 0:
raise Exception("kwargs are not supported")
return self.cf(*args)
new_args = []
for arg in args:
if isinstance(arg, str):
new_args.append(arg.encode("utf-8"))
else:
new_args.append(arg)
return self.cf(*new_args)


def ccall(f):
Expand Down