Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从共享库调用函数?_C++_Linux_Dll_Shared Libraries_Dynamic Linking - Fatal编程技术网

C++ 如何从共享库调用函数?

C++ 如何从共享库调用函数?,c++,linux,dll,shared-libraries,dynamic-linking,C++,Linux,Dll,Shared Libraries,Dynamic Linking,从共享库/dll调用函数最简单、最安全的方法是什么?我最感兴趣的是在linux上做这件事,但如果有一种独立于平台的方式会更好 如果用户已经将自己版本的foo编译到一个共享库中,是否有人可以提供示例代码来说明如何进行以下工作 // function prototype, implementation loaded at runtime: std::string foo(const std::string); int main(int argc, char** argv) { LoadLibr

从共享库/dll调用函数最简单、最安全的方法是什么?我最感兴趣的是在linux上做这件事,但如果有一种独立于平台的方式会更好

如果用户已经将自己版本的
foo
编译到一个共享库中,是否有人可以提供示例代码来说明如何进行以下工作

// function prototype, implementation loaded at runtime:
std::string foo(const std::string);

int main(int argc, char** argv) {
  LoadLibrary(argv[1]); // loads library implementing foo
  std::cout << "Result: " << foo("test");
  return 0;
}
//函数原型,运行时加载的实现:
std::string foo(const std::string);
int main(int argc,字符**argv){
LoadLibrary(argv[1]);//加载实现foo的库
您需要在Linux上使用std::cout。请参阅本页末尾的示例。
在Windows上:。

是一个用于加载DLL的Windows函数。您可以使用检查符号是否存在。在Linux/Unix上,您需要/。要在跨平台中执行此操作,您可以编写一个函数,使用预处理器调用这两种方法之一,例如:

int loadlibrary(char* library)
{
#ifdef _WIN32
    /* do windows code */

#endif
#ifdef _LINUX
    /* do linux code */

#endif
}

<>这是一种实现这种事情的方法。你可以通过在自己的源树中包含不同的头来实现函数的特定平台实现。这可能是一个更好的方法。在任何一种情况下,想法都是从底层API中抽象出来。

< P> <强>注:< /强>:你正在传递C++对象。(在这种情况下,STL字符串)在库调用周围。在这个级别<强> >有强>没有标准C++,所以要么尝试避免绕过C++对象,要么确保您的库和程序都是用同一编译器构建的(理想地是同一台机器上的同一编译器,以避免任何微妙的配置相关的惊奇)。

不要忘记在库代码中声明导出的方法

如上所述,这里有一些代码实现了您所说的您想要实现的目标:

typedef std::string (*foo_t)(const std::string);
foo_t foo = NULL;

...

# ifdef _WIN32
  HMODULE hDLL = ::LoadLibrary(szMyLib);
  if (!hDll) { /*error*/ }
  foo = (foo_t)::GetProcAddress(hDLL, "foo");
# else
  void *pLib = ::dlopen(szMyLib, RTLD_LAZY);
  if (!pLib) { /*error*/ }
  foo = (foo_t)::dlsym(pLib, "foo");
# endif
  if (!foo) { /*error*/ }

  ...

  foo("bar");

  ...

# ifdef _WIN32
  ::FreeLibrary(hDLL);
# else
  ::dlclose(pLib);
# endif
#ifdef _WIN32
#include <windows.h>
typedef HANDLE my_lib_t;
#else
#include <dlfcn.h>
typedef void* my_lib_t;
#endif

my_lib_t MyLoadLib(const char* szMyLib) {
# ifdef _WIN32
  return ::LoadLibraryA(szMyLib);
# else //_WIN32
  return ::dlopen(szMyLib, RTLD_LAZY);
# endif //_WIN32
}

void MyUnloadLib(my_lib_t hMyLib) {
# ifdef _WIN32
  return ::FreeLibrary(hMyLib);
# else //_WIN32
  return ::dlclose(hMyLib);
# endif //_WIN32
}

void* MyLoadProc(my_lib_t hMyLib, const char* szMyProc) {
# ifdef _WIN32
  return ::GetProcAddress(hMyLib, szMyProc);
# else //_WIN32
  return ::dlsym(hMyLib, szMyProc);
# endif //_WIN32
}

typedef std::string (*foo_t)(const std::string);
typedef int (*bar_t)(int);
my_lib_t hMyLib = NULL;
foo_t foo = NULL;
bar_t bar = NULL;

...

  if (!(hMyLib = ::MyLoadLib(szMyLib)) { /*error*/ }
  if (!(foo = (foo_t)::MyLoadProc(hMyLib, "foo")) { /*error*/ }
  if (!(bar = (bar_t)::MyLoadProc(hMyLib, "bar")) { /*error*/ }

  ...

  foo("bar");
  bar(7);

  ...

  ::MyUnloadLib(hMyLib);
您可以进一步对其进行抽象:

typedef std::string (*foo_t)(const std::string);
foo_t foo = NULL;

...

# ifdef _WIN32
  HMODULE hDLL = ::LoadLibrary(szMyLib);
  if (!hDll) { /*error*/ }
  foo = (foo_t)::GetProcAddress(hDLL, "foo");
# else
  void *pLib = ::dlopen(szMyLib, RTLD_LAZY);
  if (!pLib) { /*error*/ }
  foo = (foo_t)::dlsym(pLib, "foo");
# endif
  if (!foo) { /*error*/ }

  ...

  foo("bar");

  ...

# ifdef _WIN32
  ::FreeLibrary(hDLL);
# else
  ::dlclose(pLib);
# endif
#ifdef _WIN32
#include <windows.h>
typedef HANDLE my_lib_t;
#else
#include <dlfcn.h>
typedef void* my_lib_t;
#endif

my_lib_t MyLoadLib(const char* szMyLib) {
# ifdef _WIN32
  return ::LoadLibraryA(szMyLib);
# else //_WIN32
  return ::dlopen(szMyLib, RTLD_LAZY);
# endif //_WIN32
}

void MyUnloadLib(my_lib_t hMyLib) {
# ifdef _WIN32
  return ::FreeLibrary(hMyLib);
# else //_WIN32
  return ::dlclose(hMyLib);
# endif //_WIN32
}

void* MyLoadProc(my_lib_t hMyLib, const char* szMyProc) {
# ifdef _WIN32
  return ::GetProcAddress(hMyLib, szMyProc);
# else //_WIN32
  return ::dlsym(hMyLib, szMyProc);
# endif //_WIN32
}

typedef std::string (*foo_t)(const std::string);
typedef int (*bar_t)(int);
my_lib_t hMyLib = NULL;
foo_t foo = NULL;
bar_t bar = NULL;

...

  if (!(hMyLib = ::MyLoadLib(szMyLib)) { /*error*/ }
  if (!(foo = (foo_t)::MyLoadProc(hMyLib, "foo")) { /*error*/ }
  if (!(bar = (bar_t)::MyLoadProc(hMyLib, "bar")) { /*error*/ }

  ...

  foo("bar");
  bar(7);

  ...

  ::MyUnloadLib(hMyLib);
\ifdef\u WIN32
#包括
typedef处理我的库;
#否则
#包括
typedef void*my_lib\t;
#恩迪夫
my_lib_t MyLoadLib(const char*szMyLib){
#ifdef_WIN32
return::LoadLibraryA(szMyLib);
#else/\u WIN32
return::dlopen(szMyLib,RTLD_-LAZY);
#endif/\u WIN32
}
void MyUnloadLib(my_lib t hMyLib){
#ifdef_WIN32
return::FreeLibrary(hMyLib);
#else/\u WIN32
return::dlclose(hMyLib);
#endif/\u WIN32
}
void*MyLoadProc(my_lib\u t hMyLib,const char*szMyProc){
#ifdef_WIN32
return::GetProcAddress(hMyLib,szMyProc);
#else/\u WIN32
return::dlsym(hMyLib,szMyProc);
#endif/\u WIN32
}
typedef std::string(*foo_t)(const std::string);
类型定义int(*bar_t)(int);
my_lib_t hMyLib=NULL;
foo_t foo=NULL;
bar\u t bar=NULL;
...
如果(!(hMyLib=::MyLoadLib(szMyLib)){/*错误*/}
if(!(foo=(foo_t)::MyLoadProc(hMyLib,“foo”){/*error*/}
if(!(bar=(bar\t)::MyLoadProc(hMyLib,“bar”){/*error*/}
...
富(“酒吧”);
酒吧(7);
...
::MyUnloadLib(hMyLib);

<代码> C++中的函数名是什么?这不会使事情变得复杂吗?而且,你在这里拼写错误的代码<代码>包含< /代码> @ SBK好点,我添加了一个前导,处理了<代码>外部“C”<代码>等。