作者:咏方舟-长江支流  日期:2026-01-30

《金质打印通》是.Net时代的标杆产品, 从2004-08-17在csdn发表第一篇技术文章开源:.NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现与应用(1) 及(2)并开源已有22年了,收到数以万计热心朋友们的电子邮件,正因此和很多.NET的开发朋友们相识成为朋友。我准备将 GoldPrinter 移植到鸿蒙,希望大家多多交流!

现在国产化是趋势,纯血鸿蒙HarmonyOS NEXT已于2025年6月20日在华为开发者大会HDC 2025正式发布HarmonyOS 6。因此,我想将《金质打印通》移植到HarmonyOS,为国产化添砖加瓦。想学习鸿蒙开发的朋友,可进入官方 开始你的鸿蒙学习之旅 。为了系统了解HarmonyOS及 ArkTS /ArkUI,我也买了两本相关开发的书,当然也看了 HarmonyOS第一课  ,有兴趣的朋友看了后可以点击 开发者能力认证。 

我在大学学习面向对象使用的是C++,上机考试也是优秀。曾经有朋友来信说他是大学老师,拿《金质打印通》作为案例给学习讲面向对象。很多年不用C++了,手生。于是问豆包,怎么快速上手。豆包给出了答案,让我们一起共勉:

作为有C#和.NET基础,且学过鸿蒙ArkTS/ArkUI的开发者,你上手C++其实有不少优势,因为很多面向对象的概念(类、继承、多态等)是共通的。结合你要移植GDI+核心逻辑的需求,分享一个快速上手的路径,附代码示例对比,帮你更快衔接:

1. 先抓“和C#的核心差异”,跳过细枝末节

C#是托管语言,C++是直接操作内存的编译型语言,这是最大区别。重点先搞定:

  • 指针与内存管理:C#的new由GC回收,C++需要手动delete(或用智能指针)。
  • 没有“类成员自动初始化”:C#会默认初始化字段(如int为0),C++不会,必须在构造函数里显式初始化。
  • 头文件机制:C#用using引用命名空间,C++需要#include头文件,且类的声明和实现分离(.h和.cpp)。

示例对比(类的定义)

C# 实现

public class Shape {
    protected int width;
    protected int height;
    
    public Shape(int w, int h) {
        width = w;
        height = h;
    }
    
    public virtual int Area() {
        return width * height;
    }
}
                

C++ 实现(头文件 + 源文件)

// 头文件 Shape.h
#ifndef SHAPE_H  // 防止重复包含
#define SHAPE_H

class Shape {
protected:
    int width;  // 不会自动初始化,需手动赋值
    int height;
public:
    Shape(int w, int h);  // 构造函数声明
    virtual int Area();   // 虚函数(类似C#的virtual)
};

#endif


// 源文件 Shape.cpp
#include "Shape.h"

Shape::Shape(int w, int h) {
    width = w;  // 必须手动初始化,否则为随机值
    height = h;
}

int Shape::Area() {
    return width * height;
}

2. 针对GDI+移植场景,聚焦“图形相关API映射”

GDI+的核心是绘图(画笔、画刷、图形对象),C++中可以用鸿蒙的Native API或标准库(如libpng等),但重点是先掌握C++操作对象的方式。

示例:模拟GDI+的“画矩形”逻辑

#include 

// 模拟GDI+的画笔类
class Pen {
private:
    int color;  // 颜色值(RGB)
public:
    // 构造函数初始化列表(比函数体内赋值更高效)
    Pen(int c) : color(c) {}
    
    int GetColor() { return color; }
};

// 模拟GDI+的Graphics类
class Graphics {
public:
    // 画矩形:参数为画笔、坐标和尺寸
    void DrawRectangle(Pen* pen, int x, int y, int w, int h) {
        std::cout << "用颜色" << pen->GetColor() 
                  << "画矩形:(" << x << "," << y << ") 宽" << w 
                  << " 高" << h << std::endl;
    }
};

int main() {
    // 手动创建对象(需手动释放)
    Pen* redPen = new Pen(0xFF0000);  // 红色画笔
    
    Graphics g;
    g.DrawRectangle(redPen, 10, 10, 100, 50);  // 绘制矩形
    
    delete redPen;  // 必须手动释放,否则内存泄漏
    return 0;
}

3. 用“智能指针”减少内存管理负担

你是老程序员,肯定知道内存泄漏的坑。C++11后的unique_ptr/shared_ptr可以像C#的GC一样自动释放内存,优先用它们:

#include   // 智能指针头文件

int main() {
    // unique_ptr:独占所有权,离开作用域自动释放
    std::unique_ptr<Pen> redPen(new Pen(0xFF0000));  // 无需手动delete
    
    Graphics g;
    // get()方法获取原始指针供API调用
    g.DrawRectangle(redPen.get(), 10, 10, 100, 50);
    
    // 离开作用域时,redPen自动释放内存
    return 0;
}
        

4. 短期学习资源:抓“最小可用集”

不用啃大部头,针对你的场景,重点看:

  • B站/YouTube的“C++面向对象入门”(1-2小时就能过一遍类、继承、多态);
  • cppreference.com:查标准库API(如std::string、智能指针),比看书快;
  • 鸿蒙Native开发文档:直接看C++如何与ArkTS交互(通过NAPI),边用边学。

总结

你的优势是懂面向对象和业务逻辑,缺的是C++的语法细节和内存管理。建议:

  1. 先写几个和GDI+功能相关的小例子(如画图、图形计算),用C++复刻;
  2. 遇到语法问题(如::作用域符、virtualoverride)再针对性查;
  3. 优先用智能指针和现代C++特性(C++11及以上),减少历史包袱。

这样聚焦场景,1-2周就能上手核心开发,剩下的细节在移植过程中边做边补效率最高。

大家有什么想法,请评论区留言,有对华为移动开发ArkTS、金质打印通 (公众号GoldPrinter)有兴趣的可以关注互相交流,谢谢支持!

声明:本文作者 咏方舟-长江支流 相应内容版权归原作者所有,如需转载,请保留完整的内容及出处。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐