Eliminate the C FFI; Namespace lib API and DeviceManager

We decided to get rid of the C FFI for libs. It was becoming too intricate
and complicated. It was becoming a technical burden and expanding into
too much extra code. It's unfortunate, but we'll have to give up on getting
out-of-tree hot-loadable libraries the easy way.

It's possible to still do it with cross compilation or by keeping track
of the libstdc++ version that the running harikoff binary was compiled
against. Then we can ensure that our loadable lib code is linked against
that same libstdc++ code and this should ensure ABI stability.
This commit is contained in:
2025-01-13 21:57:11 -04:00
parent a4f96c8dfa
commit 09caf314f1
11 changed files with 197 additions and 377 deletions
+35 -155
View File
@@ -1,19 +1,32 @@
#ifndef SENSORDEVICESPEC_H
#define SENSORDEVICESPEC_H
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#endif // __cplusplus
#ifdef __cplusplus
struct SenseDeviceSpec
namespace hk {
namespace device {
class SenseDeviceSpec
{
public:
friend std::ostream& operator<<(
std::ostream& os, const SenseDeviceSpec& spec)
{
os << spec.stringify();
return os;
}
bool operator==(const SenseDeviceSpec& other) const
{
return sensorType == other.sensorType &&
provider == other.provider &&
deviceSelector == other.deviceSelector;
}
public:
char sensorType;
std::string implexor;
std::string api;
@@ -22,168 +35,35 @@ struct SenseDeviceSpec
std::vector<std::string> providerParams;
std::string deviceSelector;
friend std::ostream& operator<<(
std::ostream& os, const SenseDeviceSpec& spec);
bool operator==(const SenseDeviceSpec& other) const
{
return sensorType == other.sensorType &&
provider == other.provider &&
deviceSelector == other.deviceSelector;
}
};
struct InteroceptorDeviceSpec : public SenseDeviceSpec
{
};
struct ExtrospectorDeviceSpec : public SenseDeviceSpec
{
};
#endif // __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
struct CSenseDeviceSpec
{
#ifdef __cplusplus
CSenseDeviceSpec(const SenseDeviceSpec& spec)
: sensorType(spec.sensorType),
implexor(strdup(spec.implexor.c_str())),
api(strdup(spec.api.c_str())),
provider(strdup(spec.provider.c_str())),
deviceSelector(strdup(spec.deviceSelector.c_str()))
{
apiParams = new char*[spec.apiParams.size() + 1];
for (size_t i = 0; i < spec.apiParams.size(); ++i)
{
apiParams[i] = strdup(spec.apiParams[i].c_str());
}
apiParams[spec.apiParams.size()] = nullptr;
providerParams = new char*[spec.providerParams.size() + 1];
for (size_t i = 0; i < spec.providerParams.size(); ++i)
{
providerParams[i] = strdup(spec.providerParams[i].c_str());
}
providerParams[spec.providerParams.size()] = nullptr;
}
CSenseDeviceSpec(const CSenseDeviceSpec& other)
: sensorType(other.sensorType),
implexor(strdup(other.implexor)),
api(strdup(other.api)),
provider(strdup(other.provider)),
deviceSelector(strdup(other.deviceSelector))
{
if (other.apiParams) {
size_t apiParamsSize = 0;
while (other.apiParams[apiParamsSize] != nullptr) {
++apiParamsSize;
}
apiParams = new char*[apiParamsSize + 1];
for (size_t i = 0; i < apiParamsSize; ++i) {
apiParams[i] = strdup(other.apiParams[i]);
}
apiParams[apiParamsSize] = nullptr;
} else {
apiParams = nullptr;
}
if (other.providerParams) {
size_t providerParamsSize = 0;
while (other.providerParams[providerParamsSize] != nullptr) {
++providerParamsSize;
}
providerParams = new char*[providerParamsSize + 1];
for (size_t i = 0; i < providerParamsSize; ++i) {
providerParams[i] = strdup(other.providerParams[i]);
}
providerParams[providerParamsSize] = nullptr;
} else {
providerParams = nullptr;
}
}
~CSenseDeviceSpec(void)
{
free(implexor);
free(api);
free(provider);
free(deviceSelector);
if (apiParams)
{
for (size_t i = 0; apiParams[i] != nullptr; ++i) {
free(apiParams[i]);
}
}
delete[] apiParams;
if (providerParams)
{
for (size_t i = 0; providerParams[i] != nullptr; ++i) {
free(providerParams[i]);
}
}
delete[] providerParams;
}
std::string stringify() const
{
std::ostringstream os;
os << "Device: " << sensorType << ", Implexor: "
<< (implexor ? implexor : "NULL") << ", API: "
<< (api ? api : "NULL") << ", API Params: (";
if (apiParams)
<< implexor << ", API: " << api << ", API Params: (";
for (const auto& param : apiParams)
{
for (size_t i = 0; apiParams[i] != nullptr; ++i)
{
os << apiParams[i] << (apiParams[i + 1] == nullptr ? "" : " ");
}
os << param << " ";
}
os << "), Provider: " << (provider ? provider : "NULL")
<< ", Provider Params: (";
if (providerParams)
os << "), Provider: " << provider << ", Provider Params: (";
for (const auto& param : providerParams)
{
for (size_t i = 0; providerParams[i] != nullptr; ++i)
{
os << providerParams[i] << (providerParams[i + 1] == nullptr ? "" : " ");
}
os << param << " ";
}
os << "), Device Selector: "
<< (deviceSelector ? deviceSelector : "NULL") << std::endl;
os << "), Device Selector: " << deviceSelector << std::endl;
return os.str();
}
bool operator==(const CSenseDeviceSpec& other) const
{
return sensorType == other.sensorType &&
strcmp(provider, other.provider) == 0 &&
strcmp(deviceSelector, other.deviceSelector) == 0;
}
#endif
char sensorType;
char *implexor;
char *api;
char **apiParams;
char *provider;
char **providerParams;
char *deviceSelector;
};
inline std::ostream& operator<<(std::ostream& os, const CSenseDeviceSpec& spec)
class InteroceptorDeviceSpec : public SenseDeviceSpec
{
os << spec.stringify();
return os;
}
};
#ifdef __cplusplus
}
#endif
class ExtrospectorDeviceSpec : public SenseDeviceSpec
{
};
} // namespace device
} // namespace hk
#endif // SENSORDEVICESPEC_H