# Is there any way to use marco to define a complex struct?

**URL:** <https://users.rust-lang.org/t/is-there-any-way-to-use-marco-to-define-a-complex-struct/55642>\
**Category:** help\
**Created:** [February 15, 2021, 1:28pm UTC](https://users.rust-lang.org/t/is-there-any-way-to-use-marco-to-define-a-complex-struct/55642 "2021-02-15T13:28:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![rawptr](https://avatars.discourse-cdn.com/v4/letter/r/3e96dc/32.png) [@rawptr](https://users.rust-lang.org/u/rawptr)\
**Post date:** [February 15, 2021, 1:28pm UTC](https://users.rust-lang.org/t/is-there-any-way-to-use-marco-to-define-a-complex-struct/55642/1 "2021-02-15T13:28:32Z")

</div>

Hi, I have a C library and I want to dynamically load it in a Rust program.  
I have some function pointer definitions in C and I converted them into Rust:

```rust
pub type ptr_func1 = unsafe extern "C" fn(
    arg1: type1,
    arg2: type2,
) -> result1;

```

then I use a struct to store there all pointers and write some helper functions to call these function pointers without parentheses:

```rust
pub struct FuncPointers {
    func1: ptr_func1
}

impl FuncPointers {
    pub fn func1(&self, arg1: type1, arg2: type2) -> result1 {
        let ptr = self.func1;
        unsafe { ptr(arg1, arg2) }
    }
}

```

However there are more than 100 functions and finally code becomes ugly. Is it possible to define this struct with marcos?

Thanks.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [February 15, 2021, 1:51pm UTC](https://users.rust-lang.org/t/is-there-any-way-to-use-marco-to-define-a-complex-struct/55642/2 "2021-02-15T13:51:38Z")

</div>

Something like this?

```rust
use paste::paste;

macro_rules! func_pointers {
    ($v:vis $name:ident {$($f:ident($($arg_name:ident : $arg_ty:ty),* $(,)?) $(-> $res:ty)?),* $(,)?}) => {
        paste!{
        $(
            // using types such as PtrFunc1 here
            // to get snake_case, e.g. ptr_func1, use [<ptr_ $f>]
            $v type [<Ptr $f:camel>] = unsafe extern "C" fn($($arg_name: $arg_ty),*) $(-> $res)?;
        )*
            $v struct $name {
        $(
                $f: [<Ptr $f:camel>],
        )*
            }
            
            impl $name {
        $(
                pub fn $f(&self, $($arg_name: $arg_ty),*) $(-> $res)? {
                    let ptr = self.$f;
                    unsafe { ptr($($arg_name),*) }
                }
        )*
            }
        }
    }
}

// example usage
pub struct Type1;
pub struct Type2;
pub struct Type3;
pub struct Result1;

func_pointers!{
    pub FuncPointers {
        func1(arg1: Type1, arg2: Type2) -> Result1,
        func2(arg: Type3),
    }
}

```

([as a playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7872d7c59783424f282bb935aef91c1f))

(`paste` is [this crate](https://docs.rs/paste/1).)

---

<div class="post-metadata">

**Author:** ![rawptr](https://avatars.discourse-cdn.com/v4/letter/r/3e96dc/32.png) [@rawptr](https://users.rust-lang.org/u/rawptr)\
**Post date:** [February 15, 2021, 2:16pm UTC](https://users.rust-lang.org/t/is-there-any-way-to-use-marco-to-define-a-complex-struct/55642/3 "2021-02-15T14:16:08Z")

</div>

It works! Thank you! 😀

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [May 16, 2021, 2:16pm UTC](https://users.rust-lang.org/t/is-there-any-way-to-use-marco-to-define-a-complex-struct/55642/4 "2021-05-16T14:16:30Z")

</div>

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
