What is the best way to transfer arbitrary-precision reals using WSTP?

You might be able to pass the GMP internal array of limbs directly as a list, and then call FromDigits with base = 2^(limb size). This won't require any work on behalf of GMP, though I don't know anything about Mathematica's internals to say how efficient it would be on their end.

UPDATE: For the reverse, you could call IntegerDigits.


I'm not sure if this answers your question but it's a bit long for a comment. One efficient approach is to convert the parts before and after radix into a base that is a power of 2 e.g. 2^16, and then process that list so each bigit ("bignum digit") is encoded as a hex string.

Here is an example.

Map[StringDelete[ToString[BaseForm[#, 16]], "\n" ~~ __] &, 
 IntegerDigits[123425342345234523466674, 2^16]]

(* Out[136]= {"1a22", "e6b6", "f80", "2a35", "abb2"} *)

Let's see what this is internally:

In[137]:= InputForm[%]
Out[137]//InputForm=
{"1a22", "e6b6", "f80", "2a35", "abb2"}

A benefit to this approach is that it scales linearly* in the size of the input, whereas use of base 10 would throw in a logarithmic factor.

* I have not tested this, but it should behave as advertised.