gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:00:04 25 4
gpt4 key购买 nike

我正在尝试在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com