在 C++ 程序中如何调用动态库 (.so) 中的 C++ class 的构造函数

In C++ program how to call a constructor of C++ class which in dynamic library(.so)

我可以调用动态库(.so)中的C++常用函数class,但不知道如何调用动态库(.so)中的C++class构造函数。所以)。

JNIEXPORT jint JNICALL Java_com_example_hellobreakdd_MainActivity_helloBreak (JNIEnv *, jobject){

void *handle;

double (*cosine)(double);

char *error;

handle = dlopen("libtest.so", RTLD_NOW);

if (!handle) {
    __android_log_print(ANDROID_LOG_ERROR, "start", dlerror());
}

*(void **) (&cosine) = dlsym(handle, "Add");

printf("%f\n", (*cosine)(2.0));

dlclose(handle);

return 1;

}

class 的构造函数在您初始化 class 的实例并因此创建对象时被调用,

MyClass MyInstance(param);

假设MyClass是一个class,param是要传递给构造函数的参数,这将调用构造函数或MyClass

无法调用构造函数manually/directly。所以你必须在你的共享对象中创建一个对象,如下所示,

class shape {
 public:
    void draw();
};
extern "C" {
 Shape *maker(){
  return new Shape();
}

在这种情况下,您需要一个 class 形状的头文件来从 void 指针进行类型转换。说,

void *mkr = dlsym(hndl, "maker");  // get maker method symbol 
shape *my_shape = static_cast<shape *()>(mkr)(); //get the shape object

如果您不想调用基于 C 的函数,那么您必须找到损坏的名称并使用它来调用 maker() 函数并避免 "extern c"。在这种情况下,您可以使用 nm 命令获取 .so 文件中的符号。

而是在共享对象中创建一个全局对象,并使用上述方法获取对象实例。在这种情况下,当您使用 dlopen() 打开共享对象时,将调用构造函数。

希望这对您的问题有所帮助。

万一修改 .so 不是一个选项。我们可以通过相应地调用new和构造函数从.so手动创建一个c++ class的对象。

通常,编译器会完成这种工作,但我们可以通过一些内联汇编代码来完成。

这是在 x86 代码中创建虚拟 class 对象的示例:

asm volatile {
    "mov , %%edi\n"
    "callq *%2\n"
    "mov %%rax, %%rbx\n"
    "mov %%rbx, %%rdi\n"
    "callq *%1\n"
    "mov %%rbx, %0\n"
    : =m "my_pointer"
    : m "dummy_new", m "dummy_constructor"
    : "%edi", "%rax", "%rbx", "%rdi"
}