# Passing arrayref to C

**URL:** <https://discourse.ats-lang.org/t/passing-arrayref-to-c/290>\
**Category:** Google Group\
**Created:** [November 18, 2015, 1:04am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290 "2015-11-18T01:04:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 1:04am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/1 "2015-11-18T01:04:06Z")

</div>

Suppose I have:

%{^  
uint8 funA(uint8\* data) { return(0); } // Some array operation happens in  
here  
uint8\_t data[256]; // Some place to hold data for funA to work with  
%}

// A macro to access the data as an arrayref  
macdef my\_data =  
$extval(arrayref(uint8, 256),“data”)

// And ATS version of the function  
fun funA\_ (cPtr0(uint8)) : uint8 = “mac#funA”

val v = funA\_(ptr2cptr(my\_data)) // The compiler does not like this

// Get a value for use  
val v’ = my\_data[0]

Given above, ptr2cptr does not work on the array ref. What is the proper  
way to pass my\_data into the C call?

The assumption here is that funA will never go beyond 256 values into the  
passed in data. This is because of a hardware limitation where a count is a  
byte. So it is safe. So if ATS deals with arrayref(uint8, 256), things  
can’t get into trouble. But I need to pass the ATS array into C to get  
something in hardware done.

A secondary question.

fun funB(val: arrayref(uint8,256)):uint8 =

val v = funB(my\_data)

Is this the proper way to define a function that takes the arrayref? Or is  
there some signature with and ‘&’ that does this like for a var?

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 4:20pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/2 "2015-11-18T16:20:56Z")

</div>

I think there may have been a problem with my make. After a make clean, it  
showed up.

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 7:01pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/3 "2015-11-18T19:01:42Z")

</div>

Yep, was packing. This fixed it.

_#pragma_ pack(push, 1)

_typedef_

_struct_ {

uint8\_t err;

uint16\_t word;

} err\_word;

_#pragma_ pack(pop)

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 5:46am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/4 "2015-11-18T05:46:51Z")

</div>

This can be done but it is a bit tricky.

Usually, such a function is given the following interface:

fun i2c\_read\_byte  
(address: uint8, byte1: &uint8 \>\> \_, byte2: &uint8 \>\> \_): void

Also, how about the following interface:

fun i2c\_read\_byte(address: uint8): uint16On Wed, Nov 18, 2015 at 12:38 AM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> Ok, I see now.
> 
> So now I have:
> 
> implement i2c\_read\_byte(address: uint8): (uint8, uint8) = let
> 
> How do I export this so that C can call it?
> 
> I saw from the book that the tuple becomes a struct. But it did not cover  
> how to make the function. Is there some example of how to do this?
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/a884f717-2c44-495a-ac84-eba74765ee57%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/a884f717-2c44-495a-ac84-eba74765ee57%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/a884f717-2c44-495a-ac84-eba74765ee57%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/a884f717-2c44-495a-ac84-eba74765ee57%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 4:06pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/5 "2015-11-18T16:06:05Z")

</div>

Oh, I was reading after that point and missed that paragraph. I’ll test now  
and confirm the array ref passes a pointer, etc.

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 7:11pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/6 "2015-11-18T19:11:13Z")

</div>

Interesting :)On Wednesday, November 18, 2015 at 2:01:42 PM UTC-5, Mike Jones wrote:

> Yep, was packing. This fixed it.
> 
> _#pragma_ pack(push, 1)
> 
> _typedef_
> 
> _struct_ {
> 
> uint8\_t err;
> 
> uint16\_t word;
> 
> } err\_word;
> 
> _#pragma_ pack(pop)

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 1:20am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/7 "2015-11-18T01:20:22Z")

</div>

Why funA\_ is not given the following type instead:

fun funA\_ : arrayref(uint8, 256) → uint8

> > val v = funA\_(ptr2cptr(my\_data)) // The compiler does not like this

ptr2cptr takes pointer but my\_data is an arrayref.

> > fun funB(val: arrayref(uint8,256)):uint8 =

Yes. ‘val’ is a keyword and should probably be replaced.On Tue, Nov 17, 2015 at 8:04 PM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> Suppose I have:
> 
> %{^  
> uint8 funA(uint8\* data) { return(0); } // Some array operation happens in  
> here  
> uint8\_t data[256]; // Some place to hold data for funA to work with  
> %}
> 
> // A macro to access the data as an arrayref  
> macdef my\_data =  
> $extval(arrayref(uint8, 256),“data”)
> 
> // And ATS version of the function  
> fun funA\_ (cPtr0(uint8)) : uint8 = “mac#funA”
> 
> val v = funA\_(ptr2cptr(my\_data)) // The compiler does not like this
> 
> // Get a value for use  
> val v’ = my\_data[0]
> 
> Given above, ptr2cptr does not work on the array ref. What is the proper  
> way to pass my\_data into the C call?
> 
> The assumption here is that funA will never go beyond 256 values into the  
> passed in data. This is because of a hardware limitation where a count is a  
> byte. So it is safe. So if ATS deals with arrayref(uint8, 256), things  
> can’t get into trouble. But I need to pass the ATS array into C to get  
> something in hardware done.
> 
> A secondary question.
> 
> fun funB(val: arrayref(uint8,256)):uint8 =
> 
> val v = funB(my\_data)
> 
> Is this the proper way to define a function that takes the arrayref? Or is  
> there some signature with and ‘&’ that does this like for a var?
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 4:02am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/8 "2015-11-18T04:02:26Z")

</div>

Are you saying the following below would work? That by defining funA\_ with  
an array ref a pointer would be passed to the C version funA?

%{^  
uint8 funA(uint8\* data) { return(0); } // Some array operation happens in  
here  
uint8\_t data[256]; // Some place to hold data for funA to work with  
%}

fun funA\_ (arrayref(uint8, 256) : uint8 = “mac#funA”

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 5:38am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/9 "2015-11-18T05:38:27Z")

</div>

Ok, I see now.

So now I have:

implement i2c\_read\_byte(address: uint8): (uint8, uint8) = let

How do I export this so that C can call it?

I saw from the book that the tuple becomes a struct. But it did not cover  
how to make the function. Is there some example of how to do this?

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 6:57pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/10 "2015-11-18T18:57:10Z")

</div>

Ok, I’m closer. Compiles. Runs. But having some problem with return values.

In ATS:

%{^  
uint8\_t i2c\_data[256];  
%}

macdef i2c\_data =  
$extval(arrayref(uint8, 256),“i2c\_data”)

fun i2c\_read\_byte\_data (uint8, uint8)  
: (uint8, uint8) = "ext#i2c\_read\_byte\_data\_c"  
implement i2c\_read\_byte(address: uint8): (uint8, uint8) = let  
var err: uint8 = err (0, u8)  
val () = ifnerr(i2c\_start(), err, 1, u8)  
val () = ifnerr(i2c\_write(wa address), err, 2, u8)  
val () = ifnerr(i2c\_repeated\_start(), err, 3, u8)  
val () = ifnerr(i2c\_read(), err, 4, u8)  
val () = ifnerr(i2c\_stop(i2c\_data), err, 5, u8)  
in (err, i2c\_data[0]) end

In C, supporting i2c\_stop(i2c\_data) above in ATS:

uint8\_t i2c\_stop(uint8\_t \*data)  
{  
CyU3PReturnStatus\_t status = CY\_U3P\_SUCCESS;

CyU3PDebugPrint (2, “I2C Stop\r\n”);

if (read)  
{  
status = CyU3PI2cReceiveBytes (&shared\_preamble, shared\_data,  
shared\_data\_len, 0);  
memcpy(data, shared\_data, shared\_data\_len);  
}  
else  
{  
if (shared\_data\_len == 0)  
shared\_data[shared\_data\_len++] =  
shared\_preamble.buffer[–shared\_preamble.length];  
status = CyU3PI2cTransmitBytes (&shared\_preamble, shared\_data,  
shared\_data\_len, 0);  
}

return((uint8\_t)status);  
}

In C application code:

_typedef_

_struct_ {

uint8\_t err;

uint16\_t byte;

} err\_byte;

_extern_ err\_byte _i2c\_read\_byte\_data\_c_(uint8\_t, uint8\_t);

```
err_byte sb;

uint8_t b; 

sb = i2c_read_byte_data_c(0x30, 0x00);

status = sb.err;

b = sb.byte;

```

In the debugger while stopped inside i2c\_stop() (C code), I look at  
i2c\_data and see that it is set to 0x01. But what is returned to the  
err\_byte struct is a 0x00.

This implies that in the ATS, the code in (err, i2c\_data[0]) end is failing  
to index into the C array i2c\_data, or the mapping to the returned struct  
is failing. Is there some problem with my C declaration of the struct?  
Could there be a memory alignment issue requiring some forced packing or  
something?

Note this is a 32 bit ARM 9. And I am not using the C99 option during  
compilation, I’m using whatever the default is for the Cypress make system.

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 4:19pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/11 "2015-11-18T16:19:24Z")

</div>

If i2c\_read\_byte\_data is implemented, then the compiler should generate  
i2c\_read\_byte\_data\_c.On Wed, Nov 18, 2015 at 11:12 AM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> The compiler seems to generate the \_c names for the write, but not the  
> read. Looks like the compiler can’t handled the struct return and just  
> ignores the ext def.
> 
> fun i2c\_read\_byte\_data (uint8, uint8)  
> : (uint8, uint8) = “ext#i2c\_read\_byte\_data\_c”  
> fun i2c\_write\_byte\_data (uint8, uint8, uint8)  
> : uint8 = “ext#i2c\_write\_byte\_data\_c”  
> fun i2c\_read\_word\_data (uint8, uint8)  
> : (uint8, uint16) = “ext#i2c\_read\_word\_data\_c”  
> fun i2c\_write\_word\_data (uint8, uint8, uint16)  
> : uint8 = “ext#i2c\_write\_word\_data\_c”
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/4d58850c-9d05-4dea-bbe4-1c16a8e8bcaf%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/4d58850c-9d05-4dea-bbe4-1c16a8e8bcaf%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/4d58850c-9d05-4dea-bbe4-1c16a8e8bcaf%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/4d58850c-9d05-4dea-bbe4-1c16a8e8bcaf%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 5:05am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/12 "2015-11-18T05:05:55Z")

</div>

It seems that you need the following line:

staload \_ = "prelude/DATS/unsafe.dats"On Wed, Nov 18, 2015 at 12:03 AM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> I only used different names to make the example clear.
> 
> I’m having difficulty getting it to compile, so here is the exact code:
> 
> fun i2c\_stop (arrayref(uint8, 256))  
> : uint8 = “mac#i2c\_stop”
> 
> %{^  
> uint8\_t i2c\_data[256];  
> %}
> 
> macdef i2c\_data =  
> $extval(arrayref(uint8, 256),“i2c\_data”)
> 
> implement i2c\_read\_byte(address: uint8): (uint8, uint8) = let  
> var b: uint8 = u8(0)  
> var err: uint8 = err (0, u8)  
> val () = ifnerr(i2c\_start(), err, 1, u8)  
> val () = ifnerr(i2c\_write(wa address), err, 2, u8)  
> val () = ifnerr(i2c\_read(), err, 3, u8)  
> val () = ifnerr(i2c\_stop(i2c\_data), err, 4, u8)  
> in (err, i2c\_data[0]) end
> 
> I’m getting errors like:
> 
> /\*  
> emit\_instr: loc0 = /opt/ATS/ATS2-Postiats-0.2.4/prelude/DATS/array.dats:  
> 1971(line=63, offs=45) – 1989(line=63, offs=63)  
> \*/  
> ATSINSmove(tmpret33\_\_1,  
> PMVtmpltcstmat[0](ptr0\_get\<S2Eapp(S2Ecst(g0uint\_t0ype);  
> S2Eextkind(atstype\_uint8))\>)(tmp34\_\_1)) ;
> 
> DATS/smbus\_dats.c:1036:43: error: ‘ptr0\_get’ undeclared (first use in this  
> function)  
> ATSINSmove(tmpret33\_\_1,  
> PMVtmpltcstmat[0](ptr0\_get\<S2Eapp(S2Ecst(g0uint\_t0ype);  
> S2Eextkind(atstype\_uint8))\>)(tmp34\_\_1)) ;
> 
> DATS/smbus\_dats.c:1036:66: error: ‘g0uint\_t0ype’ undeclared (first use in  
> this function)  
> ATSINSmove(tmpret33\_\_1,  
> PMVtmpltcstmat[0](ptr0\_get\<S2Eapp(S2Ecst(g0uint\_t0ype);  
> S2Eextkind(atstype\_uint8))\>)(tmp34\_\_1)) ;
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/34bf8276-27ff-4fd9-851e-c7c37179d76e%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/34bf8276-27ff-4fd9-851e-c7c37179d76e%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/34bf8276-27ff-4fd9-851e-c7c37179d76e%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/34bf8276-27ff-4fd9-851e-c7c37179d76e%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 1:44am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/13 "2015-11-18T01:44:16Z")

</div>

By the way, I would like to suggest a different style, which you  
may try later when you become more comfortable with ATS.

When I see:

uint8\_t data[256];

my immediate reflex is that I can now have the following two functions:

fun{} data\_get\_at : natLt(256) → uint8  
fun{} data\_set\_at : (natLt(256), uint8) → void

If ‘data’ is read-only, then ‘data\_set\_at’ is not available. Also, ‘data’  
can be  
shared among threads if that is what you want.

If you really need to call ‘funA’ in ATS, you can do

val () = $extfcall(void, “funA”, $extval(ptr, “data”))On Tue, Nov 17, 2015 at 8:04 PM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> Suppose I have:
> 
> %{^  
> uint8 funA(uint8\* data) { return(0); } // Some array operation happens in  
> here  
> uint8\_t data[256]; // Some place to hold data for funA to work with  
> %}
> 
> // A macro to access the data as an arrayref  
> macdef my\_data =  
> $extval(arrayref(uint8, 256),“data”)
> 
> // And ATS version of the function  
> fun funA\_ (cPtr0(uint8)) : uint8 = “mac#funA”
> 
> val v = funA\_(ptr2cptr(my\_data)) // The compiler does not like this
> 
> // Get a value for use  
> val v’ = my\_data[0]
> 
> Given above, ptr2cptr does not work on the array ref. What is the proper  
> way to pass my\_data into the C call?
> 
> The assumption here is that funA will never go beyond 256 values into the  
> passed in data. This is because of a hardware limitation where a count is a  
> byte. So it is safe. So if ATS deals with arrayref(uint8, 256), things  
> can’t get into trouble. But I need to pass the ATS array into C to get  
> something in hardware done.
> 
> A secondary question.
> 
> fun funB(val: arrayref(uint8,256)):uint8 =
> 
> val v = funB(my\_data)
> 
> Is this the proper way to define a function that takes the arrayref? Or is  
> there some signature with and ‘&’ that does this like for a var?
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/e5d3c479-17fa-449a-a0da-641573f976ab%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 2:42pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/14 "2015-11-18T14:42:03Z")

</div>

Ok, let’s start with a simpler one:

fun i2c\_write\_byte\_data (uint8, uint8, uint8)  
: uint8  
implement i2c\_read\_byte\_data(address: uint8, command: uint8): (uint8,  
uint8) = let

This generated:  
/\*  
local: wa\_0$0(level=0)  
global: wa\_0$0(level=0), i2c\_write\_byte\_data$54$0(level=0)  
local:  
global:  
\*/  
ATSextern()  
atstkind\_t0ype(atstype\_uint8)  
\_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data(atstkind\_t0ype(atstype\_uint8)  
arg0, atstkind\_t0ype(atstype\_uint8) arg1, atstkind\_t0ype(atstype\_uint8)  
arg2)  
{

I then call it like this:

extern  
uint8\_t \_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data(uint8\_t  
arg0, uint8\_t arg1, uint8\_t arg2);

uint8\_t v  
= \_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data(0x00,  
0x00, 0x00);

And it compiles. But what is a good way to deal with this long prefix? All  
I can think of is to wrap a macro around it like:

#define i2c\_write\_byte\_data  
\_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data

But this will result in messy compiler errors.

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 5:23am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/15 "2015-11-18T05:23:26Z")

</div>

I had this:  
staload “prelude/SATS/unsafe.sats”

But this works when added:  
staload \_ = “prelude/DATS/unsafe.dats”

---

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [November 18, 2015, 4:12pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/16 "2015-11-18T16:12:39Z")

</div>

The compiler seems to generate the \_c names for the write, but not the  
read. Looks like the compiler can’t handled the struct return and just  
ignores the ext def.

fun i2c\_read\_byte\_data (uint8, uint8)  
: (uint8, uint8) = "ext#i2c\_read\_byte\_data\_c"  
fun i2c\_write\_byte\_data (uint8, uint8, uint8)  
: uint8 = "ext#i2c\_write\_byte\_data\_c"  
fun i2c\_read\_word\_data (uint8, uint8)  
: (uint8, uint16) = "ext#i2c\_read\_word\_data\_c"  
fun i2c\_write\_word\_data (uint8, uint8, uint16)  
: uint8 = “ext#i2c\_write\_word\_data\_c”

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 4:13am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/17 "2015-11-18T04:13:32Z")

</div>

It should work.

By the way, you could just use the name ‘funA’ for ‘funA\_’.On Tue, Nov 17, 2015 at 11:02 PM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> Are you saying the following below would work? That by defining funA\_ with  
> an array ref a pointer would be passed to the C version funA?
> 
> %{^  
> uint8 funA(uint8\* data) { return(0); } // Some array operation happens in  
> here  
> uint8\_t data[256]; // Some place to hold data for funA to work with  
> %}
> 
> fun funA\_ (arrayref(uint8, 256) : uint8 = “mac#funA”
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/7c85fe9a-3530-4b88-a65d-6527ecc12e8f%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/7c85fe9a-3530-4b88-a65d-6527ecc12e8f%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/7c85fe9a-3530-4b88-a65d-6527ecc12e8f%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/7c85fe9a-3530-4b88-a65d-6527ecc12e8f%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 5:29am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/18 "2015-11-18T05:29:13Z")

</div>

ptr0\_get is a template whose definition is in unsafe.dats.  
So you need to staload unsafe.dats (not just unsafe.sats).  
Otherwise, the compiler would not be able to compile ptr0\_get  
(and you saw error messages saying something about PMVtmpltcstmat[0])On Wed, Nov 18, 2015 at 12:23 AM, Mike Jones [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> I had this:  
> staload “prelude/SATS/unsafe.sats”
> 
> But this works when added:  
> staload \_ = “prelude/DATS/unsafe.dats”
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/f47ac698-802c-4861-8ee4-5fee0023cf89%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/f47ac698-802c-4861-8ee4-5fee0023cf89%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/f47ac698-802c-4861-8ee4-5fee0023cf89%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/f47ac698-802c-4861-8ee4-5fee0023cf89%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 6:02am UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/19 "2015-11-18T06:02:23Z")

</div>

The following line cause a type of the name ‘uint8\_pair\_t’  
to be defined in the generated C code:

extern typedef “uint8\_pair\_t” = (uint8, uint8)

So the interface for i2c\_read\_byte in C is

extern  
uint8\_pair\_t i2c\_read\_byte (uint8\_t address) ;On Wednesday, November 18, 2015 at 12:47:34 AM UTC-5, Mike Jones wrote:

> Note, calling this from C is silly, but I want to test before I wrap a  
> whole state machine around it. Even so, eventually, even that has to be  
> called from C. So the need is general.

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [November 18, 2015, 2:46pm UTC](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290/20 "2015-11-18T14:46:20Z")

</div>

This issue is mention in Chapter 8 of the Intro-to-ATS book:

[http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HTML/HTMLTOC/c2005.html](http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HTML/HTMLTOC/c2005.html)

extern  
fun i2c\_write\_byte\_data (…): … =  
"ext#whatever\_name\_you\_like\_in\_c\_for\_this\_function"On Wednesday, November 18, 2015 at 9:42:03 AM UTC-5, Mike Jones wrote:

> Ok, let’s start with a simpler one:
> 
> fun i2c\_write\_byte\_data (uint8, uint8, uint8)  
> : uint8  
> implement i2c\_read\_byte\_data(address: uint8, command: uint8): (uint8,  
> uint8) = let
> 
> This generated:  
> /\*  
> local: wa\_0$0(level=0)  
> global: wa\_0$0(level=0), i2c\_write\_byte\_data$54$0(level=0)  
> local:  
> global:  
> \*/  
> ATSextern()  
> atstkind\_t0ype(atstype\_uint8)  
> \_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data(atstkind\_t0ype(atstype\_uint8)  
> arg0, atstkind\_t0ype(atstype\_uint8) arg1, atstkind\_t0ype(atstype\_uint8)  
> arg2)  
> {
> 
> I then call it like this:
> 
> extern  
> uint8\_t \_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data(uint8\_t  
> arg0, uint8\_t arg1, uint8\_t arg2);
> 
> uint8\_t v  
> = \_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data(0x00,  
> 0x00, 0x00);
> 
> And it compiles. But what is a good way to deal with this long prefix? All  
> I can think of is to wrap a macro around it like:
> 
> #define i2c\_write\_byte\_data  
> \_057\_home\_057\_mike\_057\_cypress\_057\_workspace\_057\_UsbI2cRegMode\_057\_SATS\_057\_smbus\_056\_sats\_\_i2c\_write\_byte\_data
> 
> But this will result in messy compiler errors.

[Next page](https://discourse.ats-lang.org/t/passing-arrayref-to-c/290.md?page=2)
