<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
    <title>bigfish的网络博客 - 架构</title>
    <subtitle>记录技术和生活</subtitle>
    <link rel="self" type="application/atom+xml" href="https://blog.bigfisharc.cn/tags/jia-gou/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://blog.bigfisharc.cn"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-15T09:00:00+08:00</updated>
    <id>https://blog.bigfisharc.cn/tags/jia-gou/atom.xml</id>
    <entry xml:lang="zh">
        <title>从一个 helloworld 动态库到 rpi package：ABI 插件是怎样被加载的</title>
        <published>2026-10-15T09:00:00+08:00</published>
        <updated>2026-10-15T09:00:00+08:00</updated>
        
        <author>
          <name>bigfish</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.bigfisharc.cn/blog/20261015-0900-rpicha-jian-abijia-zai-ji-zhi/"/>
        <id>https://blog.bigfisharc.cn/blog/20261015-0900-rpicha-jian-abijia-zai-ji-zhi/</id>
        
        <summary type="html">&lt;p&gt;很多人第一次看到 rpi 的 Rust 插件，会把它理解成“编译出一个动态库，然后让 rpi 找到它”。这句话方向没错，但省略了最关键的部分：动态库如何证明自己是一个 rpi 插件？注册的工具如何跨过 Rust 边界？一次调用结束后，插件里的内存由谁释放？源码目录里的 crate 又是怎样变成项目里的 package 的？&lt;/p&gt;
&lt;p&gt;这篇文章从 &lt;code&gt;examples/plugin-stub&lt;/code&gt; 这样的最小 demo 开始。我们可以先从这个简单例子入手，再沿着 &lt;code&gt;rpi-plugin-sdk&lt;/code&gt;、&lt;code&gt;rpi-extensions&lt;/code&gt; 和 &lt;code&gt;rpi-cli&lt;/code&gt; 的实现，解释这条链路：&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;flowchart&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-6&quot;&gt; LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt;    A&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;插件源码\nRust crate&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt; --&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt; B&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;cdylib\n.dll / .so / .dylib&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt;    B &lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt; C&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;rpi 加载器\nlibloading&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt;    C &lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt; D&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;rpi_plugin_register&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt;    D &lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt; E&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;HostApi + ExtensionRegistry&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt;    E &lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt; F&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;RegistrySnapshot&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt;    F &lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-d-10&quot;&gt; G&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-12 z-d-5&quot;&gt;Agent 会话中的工具\n事件与其他扩展能力&lt;/span&gt;&lt;span class=&quot;z-l-13 z-d-8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的“插件”指 rpi 的 Rust 原生 ABI 扩展，不是 MCP Server，也不是一个通过 HTTP 或 stdio 运行的外部进程。我们可以先把它看成宿主进程里的一段本机可信代码：它和宿主运行在同一个进程里，因此能力强、开销低，但也意味着 ABI、内存所有权和生命周期必须非常明确。&lt;/p&gt;
&lt;p&gt;本文讨论的是 rpi 的原生 ABI 插件机制。由于 ABI、loader 和 package 命令会随仓库版本变化，下面的文件名、符号名和命令都应与所读源码版本一起核对；代码块中明确标注为“示意”的部分，不等于可直接复制运行的最小插件。文章关注一条主线：插件如何从动态库进入注册表，再被会话驱动；不把它扩展成完整的 Rust FFI 教程。&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="zh">
        <title>领域驱动设计（DDD）：从三层架构到 DDD 架构的演化</title>
        <published>2023-08-23T10:00:00+08:00</published>
        <updated>2023-08-23T10:00:00+08:00</updated>
        
        <author>
          <name>bigfish</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.bigfisharc.cn/blog/ddd-architecture/"/>
        <id>https://blog.bigfisharc.cn/blog/ddd-architecture/</id>
        
        <summary type="html">&lt;h2 id=&quot;san-ceng-jia-gou-de-wen-ti&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#san-ceng-jia-gou-de-wen-ti&quot; aria-label=&quot;Anchor link for: san-ceng-jia-gou-de-wen-ti&quot;&gt;三层架构的问题&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在前文中，我从基础代码的角度探讨了如何运用领域驱动设计（DDD）来实现高内聚低耦合的代码。本篇文章将从项目架构的角度，继续探讨三层架构与DDD之间的演化过程，以及DDD如何优化架构的问题。&lt;/p&gt;</summary>
        
    </entry>
    <entry xml:lang="zh">
        <title>领域驱动设计（DDD）：从基础代码探讨高内聚低耦合的演进</title>
        <published>2023-08-19T10:00:00+08:00</published>
        <updated>2023-08-19T10:00:00+08:00</updated>
        
        <author>
          <name>bigfish</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.bigfisharc.cn/blog/ddd-from-code/"/>
        <id>https://blog.bigfisharc.cn/blog/ddd-from-code/</id>
        
        <summary type="html">&lt;p&gt;在2019年我初次接触到领域驱动设计（Domain-Driven Design，简称DDD）的概念。在我的探索中，我发现许多有关DDD的教程过于偏重于战略设计，充斥着许多晦涩难懂的概念，导致阅读起来相当艰难。有些教程往往只是解释了DDD的概念，而未深入探讨为何要采用这种方式以及这样做能带来哪些好处，这导致很多人在实践应用DDD时遇到了诸多难题。甚至有些人为了引入DDD而在项目中强制采用DDD架构，结果却意外增加了代码的复杂性，带来了一系列潜在的风险。&lt;/p&gt;</summary>
        
    </entry>
</feed>
