[education/rkward] rkward/rbackend: Add proof of concept code for the introspection needed to bind functions to symbols, easily
Thomas Friedrichsmeier
null at kde.org
Fri May 10 17:04:24 BST 2024
Git commit a82feef32cd31cb9a46377e58d0c018378e2a94b by Thomas Friedrichsmeier.
Committed on 04/05/2024 at 22:40.
Pushed by tfry into branch 'master'.
Add proof of concept code for the introspection needed to bind functions to symbols, easily
M +1 -0 rkward/rbackend/CMakeLists.txt
A +22 -0 rkward/rbackend/rkrapi.cpp [License: GPL(v2.0+)]
M +22 -4 rkward/rbackend/rkrapi.h
https://invent.kde.org/education/rkward/-/commit/a82feef32cd31cb9a46377e58d0c018378e2a94b
diff --git a/rkward/rbackend/CMakeLists.txt b/rkward/rbackend/CMakeLists.txt
index e06855f67..dbca2a3b7 100644
--- a/rkward/rbackend/CMakeLists.txt
+++ b/rkward/rbackend/CMakeLists.txt
@@ -29,6 +29,7 @@ SET (
rkrbackendprotocol_backend.cpp
rkreventloop.cpp
rkbackendtransmitter.cpp
+ rkrapi.cpp
)
SET (
diff --git a/rkward/rbackend/rkrapi.cpp b/rkward/rbackend/rkrapi.cpp
new file mode 100644
index 000000000..48aa14587
--- /dev/null
+++ b/rkward/rbackend/rkrapi.cpp
@@ -0,0 +1,22 @@
+/*
+rkrapi - This file is part of RKWard (https://rkward.kde.org). Created: Wed May 01 2024
+SPDX-FileCopyrightText: 2024 by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
+SPDX-FileContributor: The RKWard Team <rkward-devel at kde.org>
+SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#include "rkrapi.h"
+
+void RFn::init(void *dllinfo) {
+ // TODO: This is just proof/test of concept code!
+ auto dummy_rfn = new RFn();
+ auto meta = dummy_rfn->metaObject();
+ for (int i = 0; i < meta->propertyCount(); ++i) {
+ auto prop = meta->property(i+meta->propertyOffset());
+ auto name = prop.name();
+ //RFn::Rf_warning("%d %s %d %d", i, name, prop.isReadable(), prop.isWritable());
+ //RFn::Rf_warning("%d", prop.write(dummy_rfn, prop.read(dummy_rfn))); //dummy_rfn->setProperty(name, QVariant::fromValue(nullptr))); // NOTE: Qt refuses to write nullptr as value!
+ }
+ dummy_rfn->setProperty("Rf_warning", QVariant::fromValue((void*) RFn::Rf_error));
+ RFn::Rf_warning("warning as error");
+}
diff --git a/rkward/rbackend/rkrapi.h b/rkward/rbackend/rkrapi.h
index cb6a69176..d2416b563 100644
--- a/rkward/rbackend/rkrapi.h
+++ b/rkward/rbackend/rkrapi.h
@@ -77,10 +77,26 @@ extern "C" void run_Rmainloop(void);
#define RK_DLOPEN_LIBRSO
#ifdef RK_DLOPEN_LIBRSO
-//#define IMPORT_R_API(X) static constexpr decltype(::X) &X = ::X
-#define IMPORT_R_API(X) static constexpr decltype(::X) &X =::X
+#include <QObject>
+#include <QMetaProperty>
+// Using Qt Meta-Property system for introspection, in order to automate the dlsym-calls.
+// Only the _set ## X function is actually used (for initialization). The _get ## X functions are just to keep the MOC happy.
+// The actual access happens directly via the member (X)
+#define IMPORT_R_API(X) Q_PROPERTY(void* X READ _get ## X WRITE _set ## X) \
+ public: static inline decltype(::X) *X = &::X; \
+ void _set ## X (void* v) { X = (decltype(X)) v; } \
+ void* _get ## X () { return (void*) X; }
+#define ROb(X) *(RFn::X)
+#else
+// For classic dynamic linking, set up the required members simply as aliases to the real thing
+#define IMPORT_R_API(X) static constexpr decltype(::X) &X = ::X
#define ROb(X) (RFn::X)
-struct RFn {
+#endif
+
+class RFn : public QObject {
+Q_OBJECT
+public:
+// TODO: This list should be generated, automatically, at compile time
IMPORT_R_API(CDR);
IMPORT_R_API(CDDR);
IMPORT_R_API(CAR);
@@ -146,6 +162,7 @@ IMPORT_R_API(R_chk_free);
IMPORT_R_API(R_dot_Last);
IMPORT_R_API(R_getEmbeddingDllInfo);
IMPORT_R_API(R_lsInternal3);
+IMPORT_R_API(Rprintf); // currently unused
IMPORT_R_API(R_registerRoutines);
IMPORT_R_API(R_removeVarFromFrame);
IMPORT_R_API(R_runHandlers);
@@ -255,7 +272,8 @@ IMPORT_R_API(ptr_R_Suicide);
IMPORT_R_API(ptr_R_WriteConsole);
IMPORT_R_API(ptr_R_WriteConsoleEx);
#endif
+public:
+ static void init(void* dllinfo);
};
-#endif
#endif
More information about the rkward-tracker
mailing list