About rust ffi double pointer type


Rust code

extern crate libc;

use libc::{c_char, c_int, c_void, c_ulong};

use std::ffi::{CString, CStr};
use std::mem;

pub struct Row {
    pub count: c_ulong,
    pub columns: *const *const c_void

pub struct Table {
    pub count: c_ulong,
    pub rows: *const *const Row

pub unsafe extern fn test() -> *const Table {
    let mut tables: Vec<*const Row> = Vec::new();

    let mut s: Vec<*const c_void> = Vec::new();

    for x in 0..10 {
        s.push(CString::new("test").unwrap().into_raw() as *const c_void)

        count: 10,
        columns: s.as_ptr()

        count: 1,
        rows: tables.as_ptr()


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include "rust_struct.h"

main(int argc, char **argv) {
    table *result = test();
    printf("count: %d\n", result->count);
    for (int i = 0; i < result->count; ++i)
        printf("columns: %d\n", result->rows[i]->count);
        for (int j = 0; j < result->rows[i]->count; ++j)
            printf("column %d: %s\n", j, result->rows[i]->columns[j]);



typedef struct _row {
    int count;
    void **columns;
} row;

typedef struct _table {
    int count;
    row **rows;
} table;

table *test();


i don’t know how to set double pointer on rust

when i try run test program i got this

count: 1
columns: 10
Segmentation fault: 11


I think the problem is the call to as_ptr on the tables and s Vecs. You are yielding a pointer to the data, but at the end of the test function they will be dropped and the memory freed. You probably want to call into_boxed_slice and then into_raw (or transmute like you already did with the boxes)


Yeah I notice that, but i don’t know how to hold on in memory. tank you.


You can convert Vecs to boxed slices using into_boxed_slice(), and then make Rust “forget” the box using Box::into_raw().

The caveat is that to properly free the memory afterwards, you’ll have to get back your box (from_raw()) and drop it.


Thank you it’s worked.