首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我是否可以在Linux上编译动态库,在Windows上进行链接?

问我是否可以在Linux上编译动态库,在Windows上进行链接?
EN

Stack Overflow用户
提问于 2020-12-18 02:27:10
回答 1查看 85关注 0票数 0

我运行的是Linux (特别是Ubuntu20.04),我想知道是否有一种方法可以生成一个可以在Windows机器上链接的动态库。我正在使用GNU make和一个mingw交叉编译器来尝试这样做。

以下是我为测试目的而制作的简单makefile:

代码语言:javascript
复制
CXX := x86_64-w64-mingw32-g++
CXX_FLAGS := -static-libgcc -static-libstdc++

main.exe: example.dll test_exe.o
    $(CXX) $(CXX_FLAGS) -o main.exe test_exe.o -L. -lexample

example.dll: example.o
    $(CXX) $(CXX_FLAGS) -shared -o example.dll example.o -Wl,--out-implib,libexample.a

%.o: %.cpp
    $(CXX) -c -fPIC $<

作为参考:我有一个example.hpp文件,它声明了我希望包含在库中的方法,这些方法是在example.cpp中定义的。test_exe.cpp包含我的main函数,并调用库中定义的方法。运行make会生成(我相信)目标文件example.o和test_exe.o,然后是一个名为example.dll的动态链接库和一个名为libexample.a的相应导入库,然后将所有内容链接到一个名为main.exe的可执行文件中。生成的输出似乎可以做到这一点,但我无法完全验证输出文件是否真的如我所期望的那样。

此外,我将CXX_FLAGS设置为静态链接c和c++标准库,因为当我不这样做时,我会得到一个错误消息The application was unable to start correctly (0xc000007b)。我猜这是因为默认情况下文件需要标准库的Linux版本(在Windows机器上找不到),而显式链接会覆盖这个选项吗?谷歌表示,这个错误可能表明我的机器使用了错误的应用程序版本,因此这是有意义的。

当我运行make时回显的命令是:

代码语言:javascript
复制
x86_64-w64-mingw32-g++ -c -fPIC example.cpp
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ -shared -o example.dll example.o -Wl,--out-implib,libexample.a
x86_64-w64-mingw32-g++ -c -fPIC test_exe.cpp
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ -o main.exe test_exe.o -L. -lexample

当我在Linux中进行链接时,一切都像预期的那样工作。只要.dll在当前目录中,可执行文件就会在Windows上运行,并且在删除它时会产生一个错误。

我没想到的第一件事是,无论导入库libmath.a是否存在,可执行文件都会运行。我假设我链接的是间接包装动态库的导入库,但事实似乎并非如此。有没有人知道实际发生了什么,为什么我没有链接到导入库?

我的另一个问题需要更多的解释。理想情况下,我希望能够在Linux上创建一个动态库,将其发送到Windows计算机,并将其链接到那里的任意可执行文件中。我不能完全确定这是否可能,因为Windows必须指定__declspec(dllexport),而Linux不指定,但我想知道它是否可行。我已经尝试将我的动态库和导入库(example.dll和libexample.a),以及我的库头文件(example.hpp)移动到一个目录中,其中包含一个指定了替代main方法的新文件(testapp.cpp)。

在Windows机上,我运行g++ -c testapp.cpp生成一个目标文件,然后尝试链接。当我运行g++ -o app.exe testapp.o -L. -lexample试图生成一个链接到动态库的可执行文件(通过导入库)时,我得到了以下错误:undefined reference to 'square(int)'。square(int)是在库中定义的函数,返回整数的平方。我还尝试将头文件中的函数标记为__declspec(dllimport),这会将错误消息更改为:undefined reference to '_imp___Z6squarei'。在Windows上是否有可能链接到一个最初没有为其功能指定__declspec(dllexport)的.dll (即在Linux中开发的一个)?

构建操作系统:Ubuntu20.04- g++版本9.3.0

目标操作系统: Windows 10 (在virtualbox vm中测试)- g++ 9.2.0版

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-05 07:02:39

我终于明白了。有效的命令是:g++ -o alt.exe testapp.o libexample.a。我不完全确定为什么我之前尝试的东西不能工作,但现在它确实能像预期的那样工作。

有趣的是,即使我没有指定__declspec(dllimport) anywhere,它仍然可以工作。我也不确定为什么会这样,但我最好的猜测是我仍然在使用GNU编译器,而不是windows默认的编译器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65346353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档