# How to store a term between C function calls in a foreign library

**URL:** <https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137>\
**Category:** Help!\
**Created:** [January 27, 2023, 7:53pm UTC](https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137 "2023-01-27T19:53:34Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![friguzzi](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/friguzzi/32/7045_2.png) [@friguzzi](https://swi-prolog.discourse.group/u/friguzzi)\
**Post date:** [January 27, 2023, 7:53pm UTC](https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137/1 "2023-01-27T19:53:34Z")

</div>

Hi,  
I have a foreign C library and I have a predicate implemented in C that receives a term that should be stored (for example in a global variable) for further C functions to use it.  
I have declared a global variable

```prolog
term_t arg;

```

and I have a function

```prolog
static foreign_t f1(term_t t1)
{
  arg=PL_copy_term_ref(t1);
}

```

I would another function to do something with the stored term

```prolog
static foreign_t f2()
{
   do something with arg
}

```

However, this does not work. Should I serialize the term to a string, store the string and deserialize in `f2`?  
How to serialize a term?

Thanks  
Fabrizio

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [January 27, 2023, 8:11pm UTC](https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137/2 "2023-01-27T20:11:10Z")

</div>

Perhaps `PL_record()` and `PL_recorded()` do what you want.  
[https://www.swi-prolog.org/pldoc/man?CAPI=PL\_record](https://www.swi-prolog.org/pldoc/man?CAPI=PL_record)

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [January 28, 2023, 10:46am UTC](https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137/3 "2023-01-28T10:46:26Z")

</div>

In 2013, I was working on Qt ‘porting’ of swipl-win, and Jan explained the necessity to serialize terms to exchange terms between threads:  
(from [PREDICATE.h](https://github.com/SWI-Prolog/packages-swipl-win/blob/74d84c889f8255bde2b72c0fd2619d238699bb7c/PREDICATE.h#L62))

```prolog
...   
    if ( PL_get_wchars(t.C_, NULL, &s, CVT_WRITEQ|BUF_RING) )
      return QString::fromWCharArray(s);
...

```

I could be wrong, but today, after the UTF-8 interface enhancements, I would first check how [PL\_get\_chars](https://www.swi-prolog.org/pldoc/man?CAPI=PL_get_chars) performs…

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [January 29, 2023, 4:41pm UTC](https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137/4 "2023-01-29T16:41:50Z")

</div>

You indeed need to serialize, but at @peter.ludemann suggested, PL\_record() and PL\_recorded() are a better choice. They are both faster and cover edge cases such as cyclic terms, internal sharing in terms and attributes.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [January 29, 2023, 5:25pm UTC](https://swi-prolog.discourse.group/t/how-to-store-a-term-between-c-function-calls-in-a-foreign-library/6137/5 "2023-01-29T17:25:25Z")

</div>

If you do need to serialize (e.g., `PL_record()` doesn’t work for you), see library(fastrw), or `PL_record_external()`.
