V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ShikiSuen
V2EX  ›  程序员

感觉没那个命花在 C++ 身上了。

  •  
  •   ShikiSuen · 339 天前 · 2073 次点击
    这是一个创建于 339 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我去年这阵子写了个专门用于注音输入法开发的「铁恨」注拼引擎模组,这个模组专门用来处理注音并击。产品名称取自「齐铁恨」人名,因为是他在台澎金马被国民政府接管之后、将纯正的北京口音的汉语广播在这个被殖民五十年左右的土地上。

    这个引擎一开始是用 Swift 写的,后来陆续出了 C# 版和 C++ 版。

    Swift: https://github.com/vChewing/Tekkon

    CSharp: https://github.com/vChewing/TekkonNT

    Cpp17: https://github.com/vChewing/TekkonCC

    一开始以为 C# 能开发 Windows 平台的输入法,才写了 C# 版。

    后来才知道似乎只能用 C / C++ / Rust ,所以就硬着头皮写了 C++ 版。

    因为我分身乏术+对 Windows / Linux 平台的输入法开发严重缺乏了解+实在学不来用不来 C++,所以威注音输入法到现在都只有 Swift 版。

    但是,现在,这 C++ 版我做不下去了。

    很多在其他语言里面轻车熟路的东西,在 C++ 里面都得造轮子,而且可能还会造出不知什么时候才会爆炸的不定时炸弹,哪怕我没用到任何指针。

    1.4.0 版之后,我对 Swift 版和 C# 版当中的一些与复合注音排列有关的共用处理逻辑做了一些错误纠正,但这些修改反而导致 C++ 版无法通过单元测试了。

    这边 Swift v1.4.2 版之后、我昨天又 refactor 了一下逻辑。今天我手把手将这些同步到 C++ 版(见 dynamicLayoutFix 分支),还是无法通过单元测试。

    我现在就觉得很可能就是我在造轮子的时候的某些轮子成了炸雷。

    为什么 Windows 和 Linux 的开发就不能直接使用 Swift 或者 C# 呢?或者「纯」 Rust 也行呢?为什么一定得 C / C++ 呢?输入法这种可能与任何可接受文字输入的 App 互动的东西,如果只能用这些「稍不留神就可能留下资安缺陷」的语言的话,窃以为真的很危险。

    16 条回复    2023-10-23 14:22:37 +08:00
    ShikiSuen
        1
    ShikiSuen  
    OP
       339 天前
    找出问题所在了:fixValue() 函式的 C++ 实作出问题了。
    ShikiSuen
        2
    ShikiSuen  
    OP
       339 天前
    欸不对,这实作与 Swift 版完全一致………
    ShikiSuen
        3
    ShikiSuen  
    OP
       339 天前
    妈的还是闹鬼。
    commonFixWhenHandlingDynamicArrangeInputs() 这个函数似乎出了问题。
    但是我仔细检查过、发现看里面写的内容跟 Swift 版都是一致的。

    会不会是 hashify() 这个轮子出了问题……
    ShikiSuen
        4
    ShikiSuen  
    OP
       339 天前   ❤️ 1
    找出元凶了:fixValue() 还是少写了一个返回条件………
    ysc3839
        5
    ysc3839  
       339 天前 via Android   ❤️ 4
    > 很多在其他语言里面轻车熟路的东西,在 C++ 里面都得造轮子,而且可能还会造出不知什么时候才会爆炸的不定时炸弹,哪怕我没用到任何指针。
    要造轮子这个个问题,可能一是跟 C++标准库本身比较克制、且更新较慢有关。二是跟 C++没有一个统一的包管理系统,比较难找到轮子。
    至于写出来的代码有问题,只能自己小心了,C++确实容易遇到一些难以发现的问题。

    > 为什么 Windows 和 Linux 的开发就不能直接使用 Swift 或者 C# 呢?或者「纯」 Rust 也行呢?为什么一定得 C / C++ 呢?
    省流:不能用 Swift 跟社区关系比较大,跟苹果也有一点关系。不能用 C#跟微软关系很大。Rust 按理说是可以的,不行的话跟社区关系比较大。
    先插一句,关于输入法开发,Windows 应该是要实现一个标准 DLL ,这个 DLL 是在目标进程中运行的。C#因为不能实现标准 DLL 所以用不了,Swift 能不能我不知道,Rust 是可以的。
    C#不容易使用 Windows API ,和微软对待 C#的策略有关。这其中有一定的历史因素,曾经的 Windows API 设计是比较像 Unix 的,比如 C 语言风格,只提供一些基础功能。就算 Windows API 功能逐渐多了起来,但整体的设计还是类似传统 Unix 那样,给人感觉简陋、难用。
    而到了 2005 年左右,市面上许多操作系统,比如 macOS 等都逐渐推出了一套“丰富 API”,这种 API 设计把许多与系统无关的、纯算法的东西都内置到了系统中,这和 Unix 的思路不同,开发者只需要使用系统 API 就能完成许多原本要直接用某个语言来实现的功能。
    正当开发者都期盼 Windows 也加入一套这样的 API 的时候,微软推出了.NET 上的 WPF ,也就是说并不会给 Windows 加入丰富 API ,而是单独推出一套包含了丰富 API 的框架。微软为什么这么做?个人认为是为了避免丰富 API 被别的语言所使用,如果内置在 Windows 中的话,其他语言也可以轻易使用,很可能抢走微软的市场份额。与此同时微软为了保持.NET 的跨平台性,提供的接口都是经过封装的,开发者并不能直接接触 Windows API ,要使用 Windows API 只能自己声明各种函数和结构体,导致长期 C#调用 Windows API 非常麻烦。
    至于 Swift ,因为苹果的操作系统内置了一套丰富 API ,以及 Swift 最初就是用来代替 Objective-C 的原因,绝大多数开发者都喜欢用苹果系统中提供的 API ,这就导致 Swift 社区里真正跨平台的库很少,所以说跟社区关系比较大,社区没人做就用不了,而深层原因则和苹果最初对 Swift 的定位以及系统 API 策略有关。
    Rust 也是需要有人做才能支持,所以也是跟社区有关。
    ohwind
        6
    ohwind  
       339 天前
    Rust 怎么会不行,如果一点 FFI 都不想用的话肯定不可能啊,但是你只需要绑定一些 C 函数,之后就能纯 Rust 写了呀
    junmoxiao
        7
    junmoxiao  
       339 天前
    缺啥轮子? boost + poco 就解决百分之八十的需求了
    c2const
        8
    c2const  
       339 天前
    0.如果接触 C++不多,可以多问问 chatGPT ,比直接看微软的文档方便,至少可以参考下它的回答。
    1.你造的 C++轮子也丢给 gpt 看看,可能能修复潜在 bug 或者给你点意见。
    2.微软文档也比较全,输入法软件开发遇到的问题,外网也能搜到解决方法。
    3.如果实在不习惯 C++语法,也不打算深入,可以在 gpt 的帮助下,封装成 OP 熟悉的 Swift 语法和官方 api ,比如字符串、编码集等等;遍用性和安全性优先,性能可以靠后,相信编译器。
    ShikiSuen
        9
    ShikiSuen  
    OP
       190 天前
    @junmoxiao boost 肥得要命。
    junmoxiao
        10
    junmoxiao  
       189 天前
    @ShikiSuen 又不是一次性用所有的 boost 库,需要啥用啥呀。而且现在 vcpkg xmake-repo 都有 boost ,安装也便捷了
    ShikiSuen
        11
    ShikiSuen  
    OP
       188 天前
    @junmoxiao ……你家 macOS 内建 vcpkg ?
    ShikiSuen
        12
    ShikiSuen  
    OP
       188 天前
    P.S.: 其实 JUCE 倒是不错。
    junmoxiao
        13
    junmoxiao  
       188 天前
    @ShikiSuen 为啥只用内建的?
    ShikiSuen
        14
    ShikiSuen  
    OP
       187 天前
    @junmoxiao 不然开源的时候给第三方编译者带来很多麻烦事情。
    C++ 这些依赖包又不像 Swift Package Manager 那样一句话引用拉倒。

    我在我电脑上编译个鼠须管都要很久、且相当一部分时间会浪费在对 boost 的部署上,
    除非用 Lotem 提供的预先编译好的 librime (里面有用到 boost )。
    junmoxiao
        15
    junmoxiao  
       186 天前
    @ShikiSuen 如果你用 xmake 的话,xmake-repo 基本已经能做到一句话引用库了。
    而且常用平台有预编译版本不需要你本地在编译,比如 boost
    ShikiSuen
        16
    ShikiSuen  
    OP
       186 天前
    @junmoxiao 感谢您推荐 xmake 。回头研究一下。

    P.S.: JUCE 是个好东西,可惜 GUI 部分对 font fallback 几乎没有支持,欸。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5271 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 08:02 · PVG 16:02 · LAX 01:02 · JFK 04:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.