Skip to content

Instantly share code, notes, and snippets.

@Gerold103
Created May 8, 2024 16:42
Show Gist options
  • Save Gerold103/cc9a0c30a756397f8fb9ff376ad572ba to your computer and use it in GitHub Desktop.
Save Gerold103/cc9a0c30a756397f8fb9ff376ad572ba to your computer and use it in GitHub Desktop.
Adserver Plugins
cmake_minimum_required(VERSION 3.0)
project(plugins)
########
add_library(mylib
mylib.cpp
)
target_compile_options(mylib PRIVATE -fPIC)
########
add_library(plugin SHARED
plugin.cpp
)
target_link_libraries(plugin
mylib
)
target_compile_options(plugin PRIVATE -fvisibility=hidden)
########
add_executable(a.out
main.cpp
)
target_link_libraries(a.out
mylib
)
#include "mylib.h"
#include "plugin.h"
#include <iostream>
#include <dlfcn.h>
class MyClassMain final : public MyClass
{
public:
MyClassMain() { ++libInc; }
void set(int val) final { MyClass::set(val + 10); }
};
int
main()
{
void* plugin = dlopen("./libplugin.so", RTLD_NOW | RTLD_LOCAL);
if (plugin == nullptr)
{
std::cout << "Couldn't load plugin\n";
return -1;
}
makeInstanceFunc* makeInstanceF = (makeInstanceFunc*)dlsym(plugin, "_Z12makeInstancev");
if (makeInstanceF == nullptr)
{
std::cout << "Couldn't load makeInstance\n";
return -1;
}
pluginPrintInfoFunc* pluginPrintInfoF = (pluginPrintInfoFunc*)dlsym(plugin, "_Z15pluginPrintInfov");
if (pluginPrintInfoF == nullptr)
{
std::cout << "Couldn't load pluginPrintInfo\n";
return -1;
}
std::cout << "Main::libInc: " << libInc << '\n';
pluginPrintInfoF();
{
MyClassMain c;
c.set(10);
std::cout << "Main class, val = " << c.get() << '\n';
std::cout << "Main::libInc: " << libInc << '\n';
pluginPrintInfoF();
}
for (int i = 0; i < 2; ++i)
{
MyClass* c = makeInstanceF();
c->set(10);
std::cout << "Plugin class, val = " << c->get() << '\n';
std::cout << "Main::libInc: " << libInc << '\n';
pluginPrintInfoF();
delete c;
}
dlclose(plugin);
return 0;
}
#include "mylib.h"
MyClass::MyClass() : myVal(0) {}
void MyClass::set(int val) { myVal = val; }
int libInc = 0;
#pragma once
class MyClass
{
public:
MyClass();
virtual ~MyClass() = default;
virtual void set(int val);
int get() const { return myVal; }
private:
int myVal;
};
extern int libInc;
#include "plugin.h"
#include "mylib.h"
#include <iostream>
namespace
{
class MyClassPlugin final : public MyClass
{
public:
MyClassPlugin() { ++libInc; }
private:
void set(int val) final { MyClass::set(val * 10); }
};
}
MyClass* makeInstance()
{
return new MyClassPlugin();
}
void pluginPrintInfo()
{
std::cout << "Plugin::libInc: " << libInc << '\n';
}
#pragma once
#include "mylib.h"
#define PLUGIN_API __attribute__((__visibility__("default")))
PLUGIN_API MyClass* makeInstance();
using makeInstanceFunc = decltype(makeInstance);
PLUGIN_API void pluginPrintInfo();
using pluginPrintInfoFunc = decltype(pluginPrintInfo);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment