rpc_interface

Attribute Macro rpc_interface 

Source
#[rpc_interface]
Expand description

Generates Windows RPC client and server code from a trait definition.

This attribute macro transforms a Rust trait into a complete Windows RPC interface, generating both client and server implementations that handle all the NDR marshalling, format strings, and Windows RPC runtime integration automatically.

§Arguments

The macro requires two arguments:

  • guid(...) - A unique interface identifier (UUID/GUID) in hexadecimal format
  • version(major.minor) - The interface version number

§Generated Types

For a trait named MyInterface, the macro generates:

  • MyInterfaceClient - A struct for making RPC calls to a server
  • MyInterfaceServerImpl - A trait to implement for hosting a server
  • MyInterfaceServer - A struct that wraps your implementation and handles RPC dispatch

§Supported Types

The following Rust types can be used for parameters and return values:

Rust TypeNDR TypeNotes
i8FC_SMALLSigned 8-bit integer
u8FC_USMALLUnsigned 8-bit integer
i16FC_SHORTSigned 16-bit integer
u16FC_USHORTUnsigned 16-bit integer
i32FC_LONGSigned 32-bit integer
u32FC_ULONGUnsigned 32-bit integer
i64FC_HYPERSigned 64-bit integer
u64FC_HYPERUnsigned 64-bit integer
&strConformant stringInput parameters only
StringConformant stringReturn values only

§Example

use windows_rpc::rpc_interface;
use windows_rpc::client_binding::{ClientBinding, ProtocolSequence};

// Define the RPC interface
#[rpc_interface(guid(0x12345678_1234_1234_1234_123456789abc), version(1.0))]
trait Calculator {
    fn add(a: i32, b: i32) -> i32;
    fn multiply(x: i32, y: i32) -> i32;
    fn greet(name: &str) -> String;
}

// Implement the server
struct CalculatorImpl;
impl CalculatorServerImpl for CalculatorImpl {
    fn add(&self, a: i32, b: i32) -> i32 {
        a + b
    }
    fn multiply(&self, x: i32, y: i32) -> i32 {
        x * y
    }
    fn greet(&self, name: &str) -> String {
        format!("Hello, {name}!")
    }
}

// Start the server
let mut server = CalculatorServer::new(CalculatorImpl);
server.register("my_endpoint").expect("Failed to register");
server.listen_async().expect("Failed to listen");

// Create a client and call methods
let binding = ClientBinding::new(ProtocolSequence::Alpc, "my_endpoint")
    .expect("Failed to create binding");
let client = CalculatorClient::new(binding);

assert_eq!(client.add(10, 20), 30);
assert_eq!(client.multiply(5, 6), 30);

server.stop().expect("Failed to stop");

§Limitations

  • Only ALPC (local RPC) protocol is currently supported
  • No support for input-output ([in, out]) parameters
  • No support for pointer types, structs, arrays, or other complex types
  • No interface security (authentication/authorization) support
  • No SEH exception handling

§Panics

The macro will fail to compile if:

  • The trait contains non-function items
  • A method uses self receiver
  • An unsupported type is used in parameters or return values
  • The GUID format is invalid