# Create \`BigInt\` directedly from MPZ pointer

**URL:** https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903
**Category:** General Usage
**Tags:** ffi, struct, constructors, integer
**Created:** [August 18, 2026, 10:16pm UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903 "2026-08-18T22:16:58Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Chrysoberyl](https://avatars.discourse-cdn.com/v4/letter/c/ed655f/32.png) [@Chrysoberyl](https://discourse.julialang.org/u/Chrysoberyl)
#### Post date: [August 18, 2026, 10:16pm UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/1 "2026-08-18T22:16:58Z")

</div>

I have some FFI code that interfaces with another library, and the target library has GNU multiprecision integers. Is it possible to create a `BigInt` directly from such a multiprecision integer pointer? The default constructor for `BigInt` is hidden, so I cannot construct a `BigInt` from limbs directly. [julia/base/gmp.jl at 6d172b025e4befc4d274d9fbc9339917a8a86b65 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/6d172b025e4befc4d274d9fbc9339917a8a86b65/base/gmp.jl#L59-L63)

```julia
mutable struct BigInt <: Signed
    alloc::Cint
    size::Cint
    d::Ptr{Limb}

    function BigInt(; nbits::Integer=0)
        b = MPZ.init2!(new(), nbits)
        finalizer(cglobal((:__gmpz_clear, libgmp)), b)
        return b
    end
end

```

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [August 19, 2026, 4:58am UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/2 "2026-08-19T04:58:56Z")

</div>

Not a solution, but my immediate concern is whether the arbitrarily large heap allocations can be tracked by Julia. Finalizers can free C-side memory when Julia-side mutable wrappers are freed, but Julia won’t inherently know how big those allocations are and adapt the heap size and GC cycles. `BigInt` are fully tracked because Julia’s allocators were set via GMP’s [allocation customization](https://gmplib.org/manual/Custom-Allocation):

> <https://github.com/JuliaLang/julia/blob/6d172b025e4befc4d274d9fbc9339917a8a86b65/base/gmp.jl#L117>

---

<div class="post-metadata">

### Author: ![Chrysoberyl](https://avatars.discourse-cdn.com/v4/letter/c/ed655f/32.png) [@Chrysoberyl](https://discourse.julialang.org/u/Chrysoberyl)
#### Post date: [August 19, 2026, 6:44am UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/3 "2026-08-19T06:44:04Z")

</div>

Is it possible to copy an existing mpz then?

---

<div class="post-metadata">

### Author: ![wheeheee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wheeheee/32/36663_2.png) [@wheeheee](https://discourse.julialang.org/u/wheeheee)
#### Post date: [August 19, 2026, 8:32am UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/4 "2026-08-19T08:32:23Z")

</div>

IIRC you could in theory create a `BigInt` with something like

```julia
eval(Expr(:new, BigInt, alloc, size, d))

```

If that’s what you’re asking about. But you would still have to manually take care of GC (as benny mentioned), register the finalizer etc…

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [August 19, 2026, 10:00am UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/5 "2026-08-19T10:00:50Z")

</div>

> [@Benny](#):
>
> were set via GMP’s [allocation customization](https://gmplib.org/manual/Custom-Allocation):

This is actually a potential problem with respect to initialization, isn’t it?

I.e. julia initializes libgmp. Then you dynamically load your foreign library. Then the foreign library might re-initialize libgmp, and we’re in trouble.

Ideally, your foreign library would first check whether libgmp is already initialized, and if so skip that step.

And likewise, julia should ideally check whether libgmp is already initialized, and if so warn / skip the initialization.

Otherwise, we could get into trouble if you embed julia: Process starts, initializes libgmp, allocates some bigints with allocator A, then loads and initializes julia, julia overwrites the existing initialization with its own allocator B, you free some old bigint, and everything sucks (using freeB on memory allocated by mallocA, bit no no).

Or am I missing something here?

---

<div class="post-metadata">

### Author: ![Chrysoberyl](https://avatars.discourse-cdn.com/v4/letter/c/ed655f/32.png) [@Chrysoberyl](https://discourse.julialang.org/u/Chrysoberyl)
#### Post date: [August 19, 2026, 6:13pm UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/6 "2026-08-19T18:13:46Z")

</div>

I don’t think this is an issue since the library I’m calling (Lean 4) does not initialize libgmp or set any allocation functions.

---

<div class="post-metadata">

### Author: ![wheeheee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wheeheee/32/36663_2.png) [@wheeheee](https://discourse.julialang.org/u/wheeheee)
#### Post date: [August 25, 2026, 5:52am UTC](https://discourse.julialang.org/t/create-bigint-directedly-from-mpz-pointer/138903/7 "2026-08-25T05:52:11Z")

</div>

The problem is that even so, if Lean 4 uses a separate instance of libgmp, when it allocates an mpz\_t it will not update Julia’s GC counters properly, which is what

```julia-auto
ccall((:__gmp_set_memory_functions, libgmp), Cvoid,
              (Ptr{Cvoid},Ptr{Cvoid},Ptr{Cvoid}),
              cglobal(:jl_gc_counted_malloc),
              cglobal(:jl_gc_counted_realloc_with_old_size),
              cglobal(:jl_gc_counted_free_with_size))

```

does. So to do what you’re suggesting, you would either have to manually handle the GC or somehow make Lean 4 use the same instance of libgmp as that instance of Julia you’re running…

So yeah, probably much easier to copy an existing `mpz_t` to a `BigInt` with `__gmpz_set`.
