c++ - 在共享库中使用 C++ 中的外部变量 - 使用 MinGW g++ 创建共享库 (dll)

标签 c++ mingw shared

我正在尝试在 Windows 上创建一个共享库。我能够在 Linux 上创建这个共享库,但在 Windows 上我遇到链接器错误。我正在使用 MinGW G++ 4.5 编译器。我会先给出linux上例子的源代码,然后给出我在windows上尝试修改的文件。

/home/nxd/Progs/C++/shared-lib>cat lib_interface.h 

#ifndef LIBINTERFACE_H
#define LIBINTERFACE_H

int func(int a);

#endif /* LIBINTERFACE_H */
/home/nxd/Progs/C++/shared-lib>cat sh_lib.cpp 
extern int b;

int func(int a)
{
 return a+b;
}
/home/nxd/Progs/C++/shared-lib>cat main.cpp 
#include <iostream>
#include "lib_interface.h"

int b;

int main()
{
 b=10;
 std::cout << func(20) << std::endl;
}

/home/nxd/Progs/C++/shared-lib>cat Makefile 
OBJS = main.o sh_lib.o

test: main.o libshared.so
 g++ -L. -o$@ main.o -lshared

main.o: main.cpp lib_interface.h
 g++ -c -Wall -fPIC $<

sh_lib.o: sh_lib.cpp lib_interface.h
 g++ -c -Wall -fPIC $<

libshared.so: sh_lib.o
 ld -shared -soname=libshared.so -o libshared.so.1 $<
 ln -s libshared.so.1 libshared.so

.PHONY: clean

clean:
 rm *.o *.so *.so.1
/home/nxd/Progs/C++/shared-lib>make
g++ -c -Wall -fPIC main.cpp
g++ -c -Wall -fPIC sh_lib.cpp
ld -shared -soname=libshared.so -o libshared.so.1 sh_lib.o
ln -s libshared.so.1 libshared.so
g++ -L. -otest main.o -lshared
/home/nxd/Progs/C++/shared-lib>LD_LIBRARY_PATH=. ./test
30

我尝试在 Windows 上使用 MinGW g++ 从 sh_lib.cpp 创建一个共享库。有这么多评论的原因是因为在我决定发布这篇文章之前我尝试了很多事情。

/home/nxd>cat sh_lib.cpp 
//extern "C" __declspec(dllimport) int b;
//#ifdef __cplusplus 
//extern "C" { 
//#endif 

__declspec(dllimport) extern int b;
//__declspec(dllimport) int b;
//extern int b;

//#ifdef __cplusplus 
//} 
//#endif 

int func(int a)
{
 return a+b;
}

这是经过各种调整的 Makefile 的相关部分。您在下面看到的传递给链接器的选项是一一添加的,以试图消除链接错误。下面的 ld 命令只是为了确保链接器确实获得了选项。前面的连字符告诉 make 运行下一个命令,即使当前命令有错误也是如此。

sh_lib.o: sh_lib.cpp lib_interface.h
 g++ -c -Wall -fPIC $<

libshared.so: sh_lib.o
 -ld -shared --enable-auto-import --unresolved-symbols=ignore-in-shared-libs   -soname=libshared.so --allow-shlib-undefined -o libshared.so.1 $<
 g++ -shared  -Wl,--unresolved-symbols=ignore-in-shared-libs  -Wl,--enable-auto-import -Wl,--allow-shlib-undefined -Wl,-soname,libshared.so -o libshared.so.1 $<

我的问题:如何使用外部变量将 sh_lib.cpp 编译成一个 dll,就像它在 linux 中的工作方式一样?我确实阅读了 stackoverflow 文章: Can't access variable in C++ DLL from a C app ,但“我认为”这两种情况之间存在细微差别。在那里他试图链接一个文件,在这里我试图创建一个共享库,使用一个没有分配存储空间的变量(extern),我想告诉链接器在创建库时忽略这个变量的存储空间- 它会在我链接到 exe 时得到解决。我目前正在使用静态链接来解决这个问题。

非常感谢您的提前帮助。

最佳答案

我在电子邮件中提供了我的答案(因为原始发布者在电子邮件中将他的问题重复到我关注的列表中),并附有修改后的示例源,可以按他的意愿工作。参见 http://mingw-users.1079350.n2.nabble.com/using-an-external-variable-in-C-in-a-shared-library-tp5521039p5521149.html .我不会费心在这里重复整个事情。只是一些关键点:

  • 变量需要 declspec(dllimport/dllexport),是
  • 要从 .exe 导入变量,您需要将 exe 视为一个 dll,因为您为它生成一个导入库以链接共享库
  • 但实际上,您不想从 exe 导入变量,因为这意味着只有具有该名称的 exe 才能使用相关的共享库
  • 相反,重新设计软件,使 API 边界中没有变量。只需让库中的一个 API 成为一个函数,以在后续调用库所需的主要(或任何地方)中“注册”数据
  • 实际上,作为一个建议,也不要在库的 API 中使用变量,纯基于函数的 API 会更好
  • 请注意,原始发布者使用的是 MinGW,所以如果您只有 MSVC 的经验,请不要费心发表评论。它们可能在某些关键方面有所不同
  • 最后,我不是真正的 C++ 人,所以我从上面的纯 C 方面谈起,抱歉。 C++ 类等肯定会使情况变得更加复杂,并在 Linux 上的 gcc/Windows 上的 gcc (MinGW)/MSVC/和其他人之间造成更烦人的差异

关于c++ - 在共享库中使用 C++ 中的外部变量 - 使用 MinGW g++ 创建共享库 (dll),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3686834/

相关文章:

c++ - 从 Xcode 调试器调用 lua_getstack

javascript - Node.js 错误 "terminate called after throwing an instance of ' std::bad_alloc' what(): std::bad_alloc"

c - 来自 MinGW 的 NetBeans 和 GDB

windows - 如何使用依赖于 libiconv 的 MinGW 安装 go 包

vb.net - 在面向对象编程中使用 .txt 文件的正确方法

c++ - 从派生类调用父类的模板函数

python - 调用 c++ 库时,如何使用 ctypes 在 Python 中传递一个字节作为引用?

c++ - 在 Windows 上使用 g++ 编译 C++ 后出现 __gxx_personality_v0 错误

multithreading - Perl线程共享数据

c++ - shared_ptr & weak_ptr 转换