Files
TransPyC/includes/vqt6/_bridge_core.cpp
T

480 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// vqt6/_bridge_core.cpp — QtCore C 桥接层实现
// ============================================================
#include "_bridge.h"
#include <QString>
#include <QByteArray>
#include <QObject>
#include <QCoreApplication>
#include <QTimer>
#include <QVariant>
#include <QEvent>
#include <QStringList>
#include <QList>
#include <QHash>
#include <QMutex>
#include <QUrl>
#include <cstring>
// ============================================================
// 资源文件标准 URL(QSS url(...) 用)
// ============================================================
extern "C" VQT6_API void vqt6_asset_url_utf8(char* buf, int buf_size, const char* name) {
if (buf == nullptr || buf_size <= 0 || name == nullptr) return;
QString url = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QStringLiteral("/") + QString::fromUtf8(name)).toString();
QByteArray u = url.toUtf8();
int n = static_cast<int>(u.size());
if (n >= buf_size) n = buf_size - 1;
std::memcpy(buf, u.constData(), static_cast<size_t>(n));
buf[n] = '\0';
}
// 全局回调表(线程安全)
namespace {
QMutex g_slot_mutex;
QHash<int, QPair<vqt6_slot_callback_t, void*>> g_slots;
int g_next_slot_id = 1000; // 避开小整数 slot_id(用户可能直接用 trigger_slot 测试)
}
// ============================================================
// QString
// ============================================================
extern "C" VQT6_API void* vqt6_qstring_create(const char* utf8) {
if (utf8 == nullptr) return nullptr;
return new QString(QString::fromUtf8(utf8));
}
extern "C" VQT6_API size_t vqt6_qstring_to_utf8(void* qstr, char* buf, size_t buf_size) {
if (qstr == nullptr || buf == nullptr || buf_size == 0) return 0;
QString* s = static_cast<QString*>(qstr);
QByteArray ba = s->toUtf8();
size_t len = static_cast<size_t>(ba.size());
if (len >= buf_size) len = buf_size - 1;
std::memcpy(buf, ba.constData(), len);
buf[len] = '\0';
return len;
}
extern "C" VQT6_API void vqt6_qstring_free(void* qstr) {
delete static_cast<QString*>(qstr);
}
extern "C" VQT6_API int vqt6_qstring_length(void* qstr) {
if (qstr == nullptr) return 0;
return static_cast<QString*>(qstr)->length();
}
extern "C" VQT6_API int vqt6_qstring_is_empty(void* qstr) {
if (qstr == nullptr) return 1;
return static_cast<QString*>(qstr)->isEmpty() ? 1 : 0;
}
extern "C" VQT6_API int vqt6_qstring_equals(void* qstr, void* other) {
if (qstr == nullptr || other == nullptr) return 0;
return *static_cast<QString*>(qstr) == *static_cast<QString*>(other) ? 1 : 0;
}
extern "C" VQT6_API void* vqt6_qstring_append(void* qstr, void* other) {
if (qstr == nullptr || other == nullptr) return nullptr;
return new QString(*static_cast<QString*>(qstr) + *static_cast<QString*>(other));
}
// ============================================================
// QByteArray
// ============================================================
extern "C" VQT6_API void* vqt6_qbytearray_create(const void* data, size_t size) {
if (data == nullptr) return new QByteArray();
return new QByteArray(static_cast<const char*>(data), static_cast<int>(size));
}
extern "C" VQT6_API void* vqt6_qbytearray_data(void* qba, size_t* out_size) {
if (qba == nullptr) return nullptr;
QByteArray* ba = static_cast<QByteArray*>(qba);
if (out_size != nullptr) *out_size = static_cast<size_t>(ba->size());
return ba->data();
}
extern "C" VQT6_API size_t vqt6_qbytearray_size(void* qba) {
if (qba == nullptr) return 0;
return static_cast<size_t>(static_cast<QByteArray*>(qba)->size());
}
extern "C" VQT6_API void vqt6_qbytearray_free(void* qba) {
delete static_cast<QByteArray*>(qba);
}
// ============================================================
// QObject
// ============================================================
extern "C" VQT6_API void vqt6_qobject_delete(void* obj) {
if (obj == nullptr) return;
delete static_cast<QObject*>(obj);
}
extern "C" VQT6_API void vqt6_qobject_delete_later(void* obj) {
if (obj == nullptr) return;
static_cast<QObject*>(obj)->deleteLater();
}
extern "C" VQT6_API void vqt6_qobject_set_object_name(void* obj, void* name) {
if (obj == nullptr || name == nullptr) return;
static_cast<QObject*>(obj)->setObjectName(*static_cast<QString*>(name));
}
extern "C" VQT6_API void* vqt6_qobject_object_name(void* obj) {
if (obj == nullptr) return nullptr;
return new QString(static_cast<QObject*>(obj)->objectName());
}
extern "C" VQT6_API void vqt6_qobject_set_parent(void* child, void* parent) {
if (child == nullptr) return;
static_cast<QObject*>(child)->setParent(static_cast<QObject*>(parent));
}
extern "C" VQT6_API void* vqt6_qobject_parent(void* obj) {
if (obj == nullptr) return nullptr;
return static_cast<QObject*>(obj)->parent();
}
extern "C" VQT6_API int vqt6_qobject_connect(void* sender, const char* signal_name,
void* receiver, const char* slot_name) {
if (sender == nullptr || receiver == nullptr || signal_name == nullptr || slot_name == nullptr)
return 0;
return QObject::connect(
static_cast<QObject*>(sender), signal_name,
static_cast<QObject*>(receiver), slot_name
) ? 1 : 0;
}
extern "C" VQT6_API int vqt6_qobject_disconnect(void* sender, const char* signal_name,
void* receiver, const char* slot_name) {
if (sender == nullptr || receiver == nullptr) return 0;
return QObject::disconnect(
static_cast<QObject*>(sender), signal_name,
static_cast<QObject*>(receiver), slot_name
) ? 1 : 0;
}
extern "C" VQT6_API void vqt6_qobject_install_event_filter(void* watched, void* filter) {
if (watched == nullptr || filter == nullptr) return;
static_cast<QObject*>(watched)->installEventFilter(static_cast<QObject*>(filter));
}
extern "C" VQT6_API void vqt6_qobject_remove_event_filter(void* watched, void* filter) {
if (watched == nullptr || filter == nullptr) return;
static_cast<QObject*>(watched)->removeEventFilter(static_cast<QObject*>(filter));
}
// ============================================================
// QCoreApplication
// ============================================================
extern "C" VQT6_API void* vqt6_qcoreapp_create(const char* app_name) {
if (app_name == nullptr) return nullptr;
int argc = 1;
static char app_name_copy[1024];
std::strncpy(app_name_copy, app_name, sizeof(app_name_copy) - 1);
app_name_copy[sizeof(app_name_copy) - 1] = '\0';
char* argv[] = { app_name_copy, nullptr };
return new QCoreApplication(argc, argv);
}
extern "C" VQT6_API void* vqt6_qcoreapp_instance(void) {
return QCoreApplication::instance();
}
extern "C" VQT6_API int vqt6_qcoreapp_exec(void* app) {
if (app == nullptr) return -1;
return static_cast<QCoreApplication*>(app)->exec();
}
extern "C" VQT6_API void vqt6_qcoreapp_quit(void* app, int exit_code) {
if (app == nullptr) return;
// 优先使用 exit_code 重载
QCoreApplication* a = static_cast<QCoreApplication*>(app);
if (a == QCoreApplication::instance()) {
a->exit(exit_code);
}
}
extern "C" VQT6_API void vqt6_qcoreapp_exit(void* app, int exit_code) {
if (app == nullptr) return;
static_cast<QCoreApplication*>(app)->exit(exit_code);
}
extern "C" VQT6_API void vqt6_qcoreapp_process_events(void* app, int flags) {
if (app == nullptr) return;
static_cast<QCoreApplication*>(app)->processEvents(static_cast<QEventLoop::ProcessEventsFlag>(flags));
}
extern "C" VQT6_API void vqt6_qcoreapp_post_event(void* receiver, void* event) {
if (receiver == nullptr || event == nullptr) return;
QCoreApplication::postEvent(static_cast<QObject*>(receiver), static_cast<QEvent*>(event));
}
extern "C" VQT6_API int vqt6_qcoreapp_send_event(void* receiver, void* event) {
if (receiver == nullptr || event == nullptr) return 0;
return QCoreApplication::sendEvent(static_cast<QObject*>(receiver), static_cast<QEvent*>(event)) ? 1 : 0;
}
extern "C" VQT6_API void* vqt6_qcoreapp_organization_name(void* app) {
if (app == nullptr) return nullptr;
return new QString(QCoreApplication::organizationName());
}
extern "C" VQT6_API void vqt6_qcoreapp_set_organization_name(void* app, void* name) {
if (app == nullptr || name == nullptr) return;
QCoreApplication::setOrganizationName(*static_cast<QString*>(name));
}
extern "C" VQT6_API void* vqt6_qcoreapp_application_name(void* app) {
if (app == nullptr) return nullptr;
return new QString(QCoreApplication::applicationName());
}
extern "C" VQT6_API void vqt6_qcoreapp_set_application_name(void* app, void* name) {
if (app == nullptr || name == nullptr) return;
QCoreApplication::setApplicationName(*static_cast<QString*>(name));
}
// ============================================================
// QTimer
// ============================================================
extern "C" VQT6_API void* vqt6_qtimer_create(void) {
return new QTimer();
}
extern "C" VQT6_API void* vqt6_qtimer_create_with_parent(void* parent) {
if (parent == nullptr) return nullptr;
return new QTimer(static_cast<QObject*>(parent));
}
extern "C" VQT6_API void vqt6_qtimer_start(void* timer, int interval_ms) {
if (timer == nullptr) return;
static_cast<QTimer*>(timer)->start(interval_ms);
}
extern "C" VQT6_API void vqt6_qtimer_stop(void* timer) {
if (timer == nullptr) return;
static_cast<QTimer*>(timer)->stop();
}
extern "C" VQT6_API void vqt6_qtimer_set_interval(void* timer, int interval_ms) {
if (timer == nullptr) return;
static_cast<QTimer*>(timer)->setInterval(interval_ms);
}
extern "C" VQT6_API int vqt6_qtimer_interval(void* timer) {
if (timer == nullptr) return 0;
return static_cast<QTimer*>(timer)->interval();
}
extern "C" VQT6_API int vqt6_qtimer_is_active(void* timer) {
if (timer == nullptr) return 0;
return static_cast<QTimer*>(timer)->isActive() ? 1 : 0;
}
extern "C" VQT6_API void vqt6_qtimer_set_single_shot(void* timer, int single_shot) {
if (timer == nullptr) return;
static_cast<QTimer*>(timer)->setSingleShot(single_shot != 0);
}
extern "C" VQT6_API int vqt6_qtimer_is_single_shot(void* timer) {
if (timer == nullptr) return 0;
return static_cast<QTimer*>(timer)->isSingleShot() ? 1 : 0;
}
// ============================================================
// QVariant
// ============================================================
extern "C" VQT6_API void* vqt6_qvariant_create_int(int value) {
return new QVariant(value);
}
extern "C" VQT6_API void* vqt6_qvariant_create_double(double value) {
return new QVariant(value);
}
extern "C" VQT6_API void* vqt6_qvariant_create_bool(int value) {
return new QVariant(value != 0);
}
extern "C" VQT6_API void* vqt6_qvariant_create_string(void* s) {
if (s == nullptr) return new QVariant();
return new QVariant(*static_cast<QString*>(s));
}
extern "C" VQT6_API int vqt6_qvariant_to_int(void* v, int* ok) {
if (v == nullptr) return 0;
bool bok = false;
int val = static_cast<QVariant*>(v)->toInt(&bok);
if (ok != nullptr) *ok = bok ? 1 : 0;
return val;
}
extern "C" VQT6_API double vqt6_qvariant_to_double(void* v, int* ok) {
if (v == nullptr) return 0.0;
bool bok = false;
double val = static_cast<QVariant*>(v)->toDouble(&bok);
if (ok != nullptr) *ok = bok ? 1 : 0;
return val;
}
extern "C" VQT6_API int vqt6_qvariant_to_bool(void* v, int* ok) {
if (v == nullptr) return 0;
bool bok = false;
bool val = static_cast<QVariant*>(v)->toBool();
if (ok != nullptr) *ok = 1;
return val ? 1 : 0;
}
extern "C" VQT6_API void* vqt6_qvariant_to_string(void* v) {
if (v == nullptr) return nullptr;
return new QString(static_cast<QVariant*>(v)->toString());
}
extern "C" VQT6_API int vqt6_qvariant_type_id(void* v) {
if (v == nullptr) return 0;
return static_cast<int>(static_cast<QVariant*>(v)->typeId());
}
extern "C" VQT6_API int vqt6_qvariant_is_valid(void* v) {
if (v == nullptr) return 0;
return static_cast<QVariant*>(v)->isValid() ? 1 : 0;
}
extern "C" VQT6_API void vqt6_qvariant_free(void* v) {
delete static_cast<QVariant*>(v);
}
// ============================================================
// QEvent
// ============================================================
extern "C" VQT6_API int vqt6_qevent_type(void* event) {
if (event == nullptr) return 0;
return static_cast<int>(static_cast<QEvent*>(event)->type());
}
extern "C" VQT6_API void vqt6_qevent_accept(void* event) {
if (event == nullptr) return;
static_cast<QEvent*>(event)->accept();
}
extern "C" VQT6_API void vqt6_qevent_ignore(void* event) {
if (event == nullptr) return;
static_cast<QEvent*>(event)->ignore();
}
extern "C" VQT6_API int vqt6_qevent_is_accepted(void* event) {
if (event == nullptr) return 0;
return static_cast<QEvent*>(event)->isAccepted() ? 1 : 0;
}
// ============================================================
// QStringList
// ============================================================
extern "C" VQT6_API void* vqt6_qstringlist_create(void) {
return new QStringList();
}
extern "C" VQT6_API void vqt6_qstringlist_append(void* list, void* str) {
if (list == nullptr || str == nullptr) return;
static_cast<QStringList*>(list)->append(*static_cast<QString*>(str));
}
extern "C" VQT6_API int vqt6_qstringlist_size(void* list) {
if (list == nullptr) return 0;
return static_cast<QStringList*>(list)->size();
}
extern "C" VQT6_API void* vqt6_qstringlist_at(void* list, int index) {
if (list == nullptr) return nullptr;
QStringList* sl = static_cast<QStringList*>(list);
if (index < 0 || index >= sl->size()) return nullptr;
return new QString(sl->at(index));
}
extern "C" VQT6_API void vqt6_qstringlist_free(void* list) {
delete static_cast<QStringList*>(list);
}
// ============================================================
// QByteArrayList
// ============================================================
extern "C" VQT6_API void* vqt6_qbytearraylist_create(void) {
return new QList<QByteArray>();
}
extern "C" VQT6_API void vqt6_qbytearraylist_append(void* list, void* qba) {
if (list == nullptr || qba == nullptr) return;
static_cast<QList<QByteArray>*>(list)->append(*static_cast<QByteArray*>(qba));
}
extern "C" VQT6_API int vqt6_qbytearraylist_size(void* list) {
if (list == nullptr) return 0;
return static_cast<QList<QByteArray>*>(list)->size();
}
extern "C" VQT6_API void* vqt6_qbytearraylist_at(void* list, int index) {
if (list == nullptr) return nullptr;
QList<QByteArray>* qbl = static_cast<QList<QByteArray>*>(list);
if (index < 0 || index >= qbl->size()) return nullptr;
return new QByteArray(qbl->at(index));
}
extern "C" VQT6_API void vqt6_qbytearraylist_free(void* list) {
delete static_cast<QList<QByteArray>*>(list);
}
// ============================================================
// 全局回调注册表
// ============================================================
extern "C" VQT6_API void vqt6_register_slot(int slot_id, void* user_data) {
QMutexLocker locker(&g_slot_mutex);
g_slots.insert(slot_id, QPair<vqt6_slot_callback_t, void*>(nullptr, user_data));
}
extern "C" VQT6_API void vqt6_unregister_slot(int slot_id) {
QMutexLocker locker(&g_slot_mutex);
g_slots.remove(slot_id);
}
extern "C" VQT6_API void vqt6_trigger_slot(int slot_id) {
// 拷贝条目后释放锁再回调,避免回调内再触发/注册时对非递归 QMutex 死锁
QPair<vqt6_slot_callback_t, void*> entry(nullptr, nullptr);
{
QMutexLocker locker(&g_slot_mutex);
auto it = g_slots.find(slot_id);
if (it == g_slots.end()) return;
entry = it.value();
}
if (entry.first != nullptr) {
entry.first(slot_id, entry.second);
}
}
extern "C" VQT6_API int vqt6_signal_register(vqt6_slot_callback_t cb, void* user_data) {
if (cb == nullptr) return -1;
QMutexLocker locker(&g_slot_mutex);
int id = ++g_next_slot_id;
g_slots.insert(id, QPair<vqt6_slot_callback_t, void*>(cb, user_data));
return id;
}
extern "C" VQT6_API void vqt6_signal_unregister(int slot_id) {
vqt6_unregister_slot(slot_id);
}
// ============================================================
// QTimer — timeout 信号 → 回调
// ============================================================
extern "C" VQT6_API void vqt6_qtimer_connect_timeout(void* timer, vqt6_slot_callback_t cb, void* user_data) {
if (timer == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QTimer*>(timer), &QTimer::timeout,
static_cast<QTimer*>(timer), [slot_id]() {
vqt6_trigger_slot(slot_id);
});
}