gpt4 book ai didi

c - 在 libpango 中调用 pango_cairo_font_map_get_default() 时出现 "GLib-GObject-CRITICAL"的原因是什么?

转载 作者:数据小太阳 更新时间:2023-10-29 03:21:54 32 4
gpt4 key购买 nike

这是一道关于 gtk/glib/libpango/libcairo 的概念题。让我们直奔问题。

我正在用一位前同事用 Go 编写的旧 C 库进行包装,在 C 代码调用的某处 pango_cairo_font_map_get_default()获取由 libpango 维护的默认 font_map

包装基本上是从Go域进入C域(外部函数接口(interface))和C端使用pthread创建一个线程最终调用pango_cairo_font_map_get_default

最初,在纯 C 端一切正常。包装后,C 代码卡在调用 pango_cairo_font_map_get_default()

printf("before call");
font_map = pango_cairo_font_map_get_default();
printf("after call");

预期的输出是:

before call
after call

实际输出是:

before call
(process:1): GLib-GObject-WARNING **: cannot register existing type 'PangoFontMap'

(process:1): GLib-CRITICAL **: g_once_init_leave: assertion 'result != 0' failed

(process:1): GLib-GObject-CRITICAL **: g_type_register_static: assertion 'parent_type > 0' failed

(process:1): GLib-CRITICAL **: g_once_init_leave: assertion 'result != 0' failed

(process:1): GLib-GObject-CRITICAL **: g_type_register_static: assertion 'parent_type > 0' failed

(process:1): GLib-GObject-WARNING **: cannot register existing type 'PangoCairoFontMap'

我自己的模拟(C 端基本上解释了我以前的同事如何使用 libpango)演示工作正常,没有警告也没有关键输出:

package main

/*
#cgo CFLAGS: -I/usr/local/include/pango-1.0
#cgo CFLAGS: -I/usr/local/include/glib-2.0
#cgo CFLAGS: -I/usr/local/include/cairo
#cgo LDFLAGS: -L/usr/local/lib -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0
#include <pango/pangocairo.h>
#include <stdio.h>
#include <pthread.h>
void hello() {
printf("threa id: %li\n", (unsigned long int)pthread_self());
PangoFontMap* font_map = pango_cairo_font_map_get_default();
PangoFontDescription* font_desc = pango_font_description_new();
pango_font_description_set_family(font_desc, "monospace");
pango_font_description_set_weight(font_desc, PANGO_WEIGHT_NORMAL);
pango_font_description_set_size(font_desc, 20 * PANGO_SCALE * 700 / 96);
PangoContext* context = pango_font_map_create_context(font_map);
PangoFont* font = pango_font_map_load_font(font_map, context, font_desc);
PangoFontMetrics* metrics = pango_font_get_metrics(font, NULL);
int width = pango_font_metrics_get_approximate_digit_width(metrics) / PANGO_SCALE;
int height = (pango_font_metrics_get_descent(metrics)
+ pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE;
printf("%d, %d\n", width, height);
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
cairo_t* cairo = cairo_create(surface);
cairo_set_source_rgb(cairo, 155 / 255.0, 155 / 255.0, 155 / 255.0);
cairo_rectangle(cairo, 0, 0, width, height);
PangoLayout* layout = pango_cairo_create_layout(cairo);
pango_layout_set_font_description(layout, font_desc);
g_object_unref(layout);
cairo_destroy(cairo);
cairo_surface_destroy(surface);
}
void* font() {
hello();
hello();
return NULL;
}
void two_threads() {
pthread_t thread1;
pthread_create(&thread1, NULL, font, NULL);
pthread_join(thread1, NULL);
pthread_t thread2;
pthread_create(&thread2, NULL, font, NULL);
pthread_join(thread2, NULL);
}
*/
import "C"
import "sync"

func main() {
wg := sync.WaitGroup{}
for i := 0; i < 1; i++ {
wg.Add(1)
go func() {
C.two_threads()
wg.Done()
}()
}
wg.Wait()
}

TL;DR: 我对pango_cairo_font_map_get_default()的理解总是会成功(线程安全,因为它使用的是1.40.4 1.el7),而且无论多少次(里面的静态内部变量) pango) 代码尝试调用。

因此,我的问题是:

  1. 什么可能导致无法注册现有类型/g_once_init_leave:断言失败
  2. 为什么这样的错误会阻塞代码?

最佳答案

问题可能是由于您在 Go 和 c 中所做的事情之间存在冲突,因为双重注册类型并且对彼此所做的事情不透明。尝试为 gtk 堆栈使用 go 绑定(bind),而不是制作自己的包装器。

关于c - 在 libpango 中调用 pango_cairo_font_map_get_default() 时出现 "GLib-GObject-CRITICAL"的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52505186/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com