Skip to content

Commit 4591db8

Browse files
authored
Merge pull request #674 from dylon/dylon/str-args
Adds support for str type to ccall
2 parents 412e89f + a7f9085 commit 4591db8

File tree

5 files changed

+32
-2
lines changed

5 files changed

+32
-2
lines changed

integration_tests/test_c_interop_02.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def f_i16_i16(x: i16) -> i16:
2424
def f_i8_i8(x: i8) -> i8:
2525
pass
2626

27+
@ccall
28+
def f_str_i32(x: str) -> i32:
29+
pass
30+
2731
def test_c_callbacks():
2832
xf64: f64
2933
xf64 = 3.3
@@ -49,4 +53,13 @@ def test_c_callbacks():
4953
xi8 = 3
5054
assert f_i8_i8(xi8) == 4
5155

56+
assert f_str_i32("Hello World!") == 12
57+
assert f_str_i32("abc") == 3
58+
assert f_str_i32("a") == 1
59+
assert f_str_i32("") == 0
60+
x: str = "Hello World!"
61+
assert f_str_i32(x) == 12
62+
x = "abc"
63+
assert f_str_i32(x) == 3
64+
5265
test_c_callbacks()

integration_tests/test_c_interop_02b.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <string.h>
2+
13
#include "test_c_interop_02b.h"
24

35
double f_f64_f64(double x) {
@@ -23,3 +25,7 @@ int16_t f_i16_i16(int16_t x) {
2325
int8_t f_i8_i8(int8_t x) {
2426
return x+1;
2527
}
28+
29+
int32_t f_str_i32(char *x) {
30+
return strlen(x);
31+
}

integration_tests/test_c_interop_02b.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int64_t f_i64_i64(int64_t x);
1010
int32_t f_i32_i32(int32_t x);
1111
int16_t f_i16_i16(int16_t x);
1212
int8_t f_i8_i8 (int8_t x);
13+
int32_t f_str_i32(char *x);
1314

1415

1516
#endif // TEST_C_INTEROP_02B

src/libasr/codegen/asr_to_c.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
114114
std::string dims = convert_dims_c(t->n_dims, t->m_dims);
115115
sub = format_type_c(dims, "bool", v.m_name, use_ref, dummy);
116116
} else if (ASRUtils::is_character(*v.m_type)) {
117-
// TODO
117+
ASR::Character_t *t = ASR::down_cast<ASR::Character_t>(v.m_type);
118+
std::string dims = convert_dims_c(t->n_dims, t->m_dims);
119+
sub = format_type_c(dims, "char *", v.m_name, use_ref, dummy);
118120
} else if (ASR::is_a<ASR::Derived_t>(*v.m_type)) {
119121
std::string indent(indentation_level*indentation_spaces, ' ');
120122
ASR::Derived_t *t = ASR::down_cast<ASR::Derived_t>(v.m_type);

src/runtime/ltypes/ltypes.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ def convert_type_to_ctype(arg):
129129
return ctypes.c_int8
130130
elif arg == CPtr:
131131
return ctypes.c_void_p
132+
elif arg == str:
133+
return ctypes.c_char_p
132134
elif arg is None:
133135
raise NotImplementedError("Type cannot be None")
134136
elif isinstance(arg, Array):
@@ -176,7 +178,13 @@ def get_crtlib_path():
176178
def __call__(self, *args, **kwargs):
177179
if len(kwargs) > 0:
178180
raise Exception("kwargs are not supported")
179-
return self.cf(*args)
181+
new_args = []
182+
for arg in args:
183+
if isinstance(arg, str):
184+
new_args.append(arg.encode("utf-8"))
185+
else:
186+
new_args.append(arg)
187+
return self.cf(*new_args)
180188

181189

182190
def ccall(f):

0 commit comments

Comments
 (0)