c++ esp32 - pointer to object - arduino-c++

I have a project for ESP32 (Vscode/platformIO) with this code working:
BCls receives in its constructor a pointer to an instance of ACls and assign it to its private _a.
So in main.cpp, I just create and instance of ACls, then inject a pointer to it into the constructor of BCls:
main.cpp
#include "ACls.h"
ACls aa;
#include "BCls.h"
BCls bb(aa);
void setup() {
bb.doSomething("hello");
}
BCls.h
#include "ACls.h"
class BCls {
public:
ACls *_a;
//ctors
BCls();
BCls(ACls *aa);
}
BCls.cpp
#include "BCls.h"
#include "ACls.h"
BCls::BCls() {
}
BCls::BCls(ACls *aa) {
_a = aa;
}
The problem:
But now I need to modify it so that, if BCls does not receive in its constructor an ACls instance, it must instantiate it internally and assign it to _a.
I tried this but it does not work (compiles ok but fails in runtime):
main.cpp
#include "BCls.h"
BCls bb;
void setup() {
bb.doSomething("hello");
}
BCls.h
class BCls {
public:
ACls *_a;
//ctors
BCls();
BCls(ACls *aa);
}
BCls.cpp
#include "ACls.h"
BCls::BCls() {
//how to instantiate here an object of class ACls and assign a pointer to it to BCls._a??
//I tried this but its not working:
ACls aTmp;
_a = &aTmp;
}
BCls::BCls(ACls *aa) {
_a = aa;
}
the exception is
rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1284
load:0x40078000,len:12808
load:0x40080400,len:3032
entry 0x400805e4
So, how should this be done?
MORE INFO:
I will try to explain deeper why I want to do this:
Lets say I have 3 classes:
SdCls -> manages everything related to a SD card module.
GpsCls -> manages everything related to a gps module.
SensorCls -> manages everything related to a temperature sensor.
And lets say both GpsCls and SensorCls, need to log some data on the sd card.
and also the project's main file needs to use the sd card to read files or whatever.
So right now, in projects main file, I instantiate SdCls, then instantiate GpsCls and SensorCls, passing the SdCls instance to their constructors. so now I can use the SD card in the projects main file, and both the gpsCls and SensorCls can use that same instance of SdCls to do their things. And everyone is happy.
But now I want these classes to be reusable in other projects. and lets say in another project, the only one that needs to access the SD card is the GpsCls. My idea with this was that, instead of instantiating the SdCls in the project main file, that I could just create the GpsCls object calling its empty constructor, and then let the GpsCls class instantiate the SdCls object it needs (as it will only be used by GpsCls)
I hope this is clearer now...

The problem you are facing is a result of the lifetime of the ACls object you want to keep a pointer to in BCls, by declaring it in the constructor, when the constructor returns, aTmp goes out of scope and is destroyed and the pointer saved no longer points to a valid ACls object.
There are a few options to solve this:
If you can afford creating a ACls for every BCls object, simply create a member ACls:
class BCls {
ACls _m_a;
ACls *_a;
public:
BCls() : _a(&_m_a) { }
BCls(ACls *aa) : _a(aa) { }
};
If you only need to create one BCls or they can share ACls object, you can declare the aTmp as static:
class BCls {
ACls *_a;
public:
BCls() {
static ACls aTmp; // Note this will be shared for all BCls objects that use this constructor
_a = &aTmp;
}
BCls(ACls *aa) : _a(aa) { }
};
If you cannot do either of the above, the best bet is to dynamically allocate ACls (or you could allocate from a static pool but that involves more work that might not be worth it on something like an ESP32; also remember to delete the object in the destructor for the BCls object if needed to not leak memory):
class BCls {
ACls *_a;
public:
BCls() {
_a = new ACls();
}
BCls(ACls *aa) : _a(aa) { }
};

Related

What's the use for Kotlin's #JvmSynthetic on a file target?

The #JvmSynthetic annotation is allowed to be used on a file, but I can't figure out what the purpose of this would be.
I was hoping I could hide a file containing a bunch of Kotlin-only extension methods from Java users, but that doesn't seem to be the case:
// Extensions.kt
#file:JvmSynthetic
#JvmSynthetic
fun Foo.mySyntheticExtension() = ...
fun Foo.myExtension() = ...
// Java usage
// This doesn't compile (as expected)
Extensions.mySyntheticExtension(foo);
// This compiles fine, so #JvmSynthetic on a file does not trickle down to all its functions
Extensions.myExtension(foo);
Even without the non-synthetic method Java users still see the cluttering ExtensionsKt class, although it appears empty to them.
If #file:JvmSynthetic doesn't hide the file('s generated class) from Java, nor trickles down the synthetic status to all functions in it, what is its intended purpose?
The original proposal that caused this annotation target to be added was KT-41884:
The rationale given was:
This would apply to the synthesized class which encapsulates top-level members. This allows hiding those members from Java when they are internal visibility.
For example:
// ManyInternals.kt, in module A
#file:JvmSynthetic
internal fun foo() {
}
internal fun bar() {
}
// Main.java, in module B
public class Main {
public static void main(String[] args) {
ManyInternalsKt.foo(); // error
}
}

Is there a way to hide the INSTANCE variable on a Kotlin singleton object

If I have code like this
object ObjectTest {
#JvmStatic
fun init() {
}
}
is it possible to hide the ObjectTest.INSTANCE variable that Kotlin automatically generates? I don't want the object to be accessible via an instance and nor will it have any instance methods, so the INSTANCE variable is just polluting autocomplete and could be confusing to potential users (This code is for a library that will be consumed by others).
Yes, you can do it, by converting an object into a plain file.
#file:JvmName("ObjectTest")
// maybe a package statement here
fun init() {
// here `init` is public static final void
}
And there's no INSTANCE object. In Kotlin this is a top-level function, but in Java it's a class named ObjectTest with a private constructor and it has a public static final void method called init.

Why are all of the classes in Rakudo's src/core/Int.pm declared with my?

Looking at the source for Int, I see that all of the classes are declared with my, which I would have thought would make them private and not available outside that file. But, they obviously are. Why do they need to be declared that way?
my class Rat { ... }
my class X::Numeric::DivideByZero { ... }
my class X::NYI::BigInt { ... }
my class Int { ... }
my subset UInt of Int where {not .defined or $_ >= 0};
my class Int does Real { # declared in BOOTSTRAP
I figure that BOOTSTRAP comment has something to do with it. In the Perl6/Metamodel/BOOTSTRAP.nqp there are lines like:
my stub Int metaclass Perl6::Metamodel::ClassHOW { ... };
The files in Rakudo's src/core/ directory are not compiled as separate modules with their own private file-level scope, but concatenated into a single file such as gen/moar/CORE.setting during the build proceess.
Sematically, this 'setting' (known as 'prelude' in other languges) forms an outer lexical scope implicitly surrounding your program.
The design is described in S02: Pseudo-packages, and parts of that section have made it into the official documentation.

Pthread Thread-Local-Singleton, when to release the TLS Key?

I implemented a kind of "thread local singleton" using pthread TLS, and i wondered how (and when) i could possibly delete the pthread_key_t in this case, because as it is now, the memory used by the TLS key will never be free'd.
The intended usage of this is to let a class A derive from ThreadLocalSingleton<A> which makes A a thread local singleton, assuming that A has only private constructors and ThreadLocalSingleton<A> is a friend of A.
Oh and also - do you see any problems with that implementation; did i overlook anything important?
#include <pthread.h>
#include <iostream>
template <class T>
class ThreadLocalSingleton
{
private:
static pthread_key_t tlsKey;
static pthread_once_t tlsKey_once;
static void tls_make_key()
{
(void)pthread_key_create(&ThreadLocalSingleton::tlsKey, ThreadLocalSingleton::tls_destructor);
}
static void tls_destructor(void* obj)
{
delete ((T*)obj);
pthread_setspecific(tlsKey, NULL); // necessary or it will call the destructor again.
}
public:
/*
* A thread-local singleton getter, the resulted object must never be released,
* it is auto-released when the thread exits.
*/
static T* getThreadInstance(void)
{
pthread_once(&tlsKey_once, ThreadLocalSingleton::tls_make_key);
T* instance = (T*)pthread_getspecific(tlsKey);
if(!instance)
{
try
{
instance = new T;
pthread_setspecific(tlsKey, instance);
}
catch (const char* ex)
{
printf("Exception during thread local singleton init: %s\n",ex);
}
}
return instance;
}
};
template <class T>
pthread_key_t ThreadLocalSingleton<T>::tlsKey;
template <class T>
pthread_once_t ThreadLocalSingleton<T>::tlsKey_once = PTHREAD_ONCE_INIT;
Your implementation looks very elegant.
According to the Open Group Specification of pthread_key_create, you don't have to set the reference to NULL in the destructor:
An optional destructor function may be associated with each key value. At thread exit, if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with that key, the value of the key is set to NULL, and then the function pointed to is called with the previously associated value as its sole argument.
I think this also implies that the key object itself will be autodestroyed by pthread. You only have to take care of what's stored behind the key, which is precisely what your delete ((T*)obj); does.

Capturing return type of unmanaged class using C++/CLI

I have a method in my native dll, that I want to use. The method returns an object of a type that is also in my native dll.I am trying to write a c++/CLI wrapper.
Now,
Can I get a return value as the object using C++/CLI and how do I do that?
Can we store and pass the native C++ object?
Should I need to create my own class resembling the native C++ class?
How would I marshal a class?
For Example,My native dll has these classes,
class X
{
/* some props and methods. */
};
Class Y
{
X* someMethod();
};
I need to wrap the someMethod class using C++/CLI. Will I be able to get the return value in the CLI?
Returning pointers to C++ objects from an exported function in a DLL is a pretty bad idea. It is a nasty memory management problem, you'd expect the client code to release the object. That can only come to a good end when both DLLs use the exact same version of the DLL version of the CRT (/MD compile option). If you can't recompile the native DLL then stop right now, you cannot make it work reliably or you'll have a big maintenance problem in the future.
Anyhoo, you need a wrapper for both classes. They should resemble this:
#pragma managed(push, off)
#include "xandy.h"
#pragma managed(pop)
using namespace System;
namespace something {
public ref class XWrapper {
X* mX;
public:
XWrapper(X* obj) : mX(obj) {}
~XWrapper() { this->!XWrapper(); }
!XWrapper() {
// Trouble is here!!!
delete mX;
}
};
public ref class YWrapper {
Y* mY;
public:
YWrapper() { mY = new Y; }
~YWrapper() { this->!YWrapper(); }
!YWrapper() { delete mY; }
XWrapper^ someMethod() {
return gcnew XWrapper(mY->someMethod());
}
};
}