说明
我一直都知道dlopen的大概用法。但是dlopen毕竟是c语言的函数,能否加载带c++类型传参的函数,我有点不确定。今天有空验证了下,是可以的。extern “C”只影响了函数在动态库中的Name Mangling,并不排斥参数和回参使用c++类型。
一个例子
test.h
#include <string>
extern "C" std::string* test(std::string info);
//定义函数指针类型名为test_t
using test_t = std::string* (*)(std::string info);
test.cpp
#include <string>
#include <stdio.h>
#include "test.h"
static std::string g_str("this is test");
std::string* test(std::string info)
{
printf("in test:%s\n", info.c_str());
return &g_str;
}
main.cpp
#include <stdio.h>
#include <string>
#include <iostream>
#include <dlfcn.h>
#include "test.h"
int main()
{
void* handle = dlopen("./libtest.so", RTLD_LAZY);
if (!handle) {
printf("Cannot open library");
return 1;
}
// reset errors
test_t testfunc = reinterpret_cast<test_t>(dlsym(handle, "test"));
if (test == nullptr) {
printf("Cannot load symbol 'test'\n");
dlclose(handle);
return 1;
}
// use it to do the calculation
printf("Calling test...\n");
auto p = testfunc("this is main");
printf("get info:%s\n", p->c_str());
return 0;
}
mk.sh
#!/bin/sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
gcc test.cpp -fPIC -shared -std=c++11 -o libtest.so
gcc main.cpp -L./ -ltest -ldl -lstdc++ -std=c++11 -o main
执行结果
代码比较 简单,一目了然。
Calling test...
in test:this is main
get info:this is test