我正在开发使用libedataserver.so的Thunderbird插件。
Addon使用js-ctypes从上面的库中调用e_source_registry_new_sync。见下面的代码:
var lib = ctypes.open("libedataserver-1.2.so.18");
var GCancellable = {};
GCancellable.cls = new ctypes.StructType("GCancellable");
var GError = {};
GError.cls = new ctypes.StructType("GError");
var ESourceRegistry = {};
ESourceRegistry.cls = new ctypes.StructType("ESourceRegistry");
ESourceRegistry.e_source_registry_new_sync =
lib.declare(
"e_source_registry_new_sync",
ctypes.default_abi,
ESourceRegistry.cls.ptr,
GCancellable.cls.ptr,
GError.cls.ptr.ptr);
//below line causes an error
var sourceRegistry = ESourceRegistry.e_source_registry_new_sync(null, null);
它在Ubuntu上运行得很好但是在Fedora 21上它打印在输出下面并挂起:
(thunderbird:2735): GLib-GObject-WARNING **: cannot register existing type 'EDBusSource'
(thunderbird:2735): GLib-GObject-CRITICAL **: g_type_interface_add_prerequisite: assertion 'G_TYPE_IS_INTERFACE (interface_type)' failed
(thunderbird:2735): GLib-CRITICAL **: g_once_init_leave: assertion 'result != 0' failed
(thunderbird:2735): GLib-GObject-WARNING **: invalid cast from 'EDBusSourceProxy' to '<invalid>'
我使用Fedora 21和evolution-data-server 3.12.11-1.fc21。
Ubuntu使用evolution-data-server 3.12.10。
我开发了一个调用e_source_registry_new_sync的简单C应用程序,它完全正常。
有人可以说明这个问题可能是什么原因吗?
@UPDATE: 我举起了Fedora bug。根据Fedora维护者的问题是由于加载libedataserver两次(我的代码和evolution-ews)引起的:
问题似乎是thunderbird自己加载libedataserver-1.2.so.18,而libcamelews.so对libedataserver-1.2.so有运行时依赖性,但这不是(在运行时)雷鸟满足-loaded libedataserver-1.2.so.18,因此再次加载,这会打破GLib类型系统。
如果我能从插件方面做些什么,请发表评论。
答案 0 :(得分:0)
您询问此功能发生的错误:https://developer.gnome.org/libedataserver/stable/ESourceRegistry.html#e-source-registry-new-sync
文档说明错误时会返回NULL
并正确设置GError
。我稍后会测试代码然后看看是什么,但我会在这里告诉你如何自己测试。
GError
不是一个opque结构。像这样定义:
var GQuark = ctypes.uint32_t;
GError.cls = new ctypes.StructType('GError', [
{'domain': GQuark},
{'code': ctypes.int},
{'message': ctypes.char.ptr}
]);
从这里采取:https://gist.github.com/Noitidart/dbe54fcd7794c8ddff6f#file-_ff-addon-snippet-gdk_giolaunch-js-L22
然后设置代码以返回如下错误:
var error = GError.cls.ptr(); // can use `null` if we dont care to see error but we want to know what is happening so we can fix it
var sourceRegistry = ESourceRegistry.e_source_registry_new_sync(null, error.address());
if (sourceRegistry.isNull()) {
console.error('An error occured when calling e_source_registry_new_sync!');
console.info('ERROR DETAILS', 'Domain:', error.contents.domain.toString(), 'Code:', error.contents.code, 'Message:', error.contents.message.readString());
}
然后根据错误详细信息查找该代码和消息,它会告诉您发生了什么,然后搜索StackOverflow或解决它的任何地方,如果它不明显。