使用 Maven NAR 插件在 Windows 上链接 DLL

发布于 2024-10-16 15:41:31 字数 2942 浏览 0 评论 0原文

我正在尝试使用 Maven NAR 插件构建一个非常简单的 C++ 程序。我已经设置了一个 Maven 模块来构建共享库,另一个用于链接库并构建使用它的可执行文件。在 Mac 上构建效果很好,我可以运行该程序。不幸的是,使用 MS Visual C++(免费版本)在 Windows (XP) 上构建失败并出现链接器错误。两台机器(操作系统和编译器除外)之间配置的唯一区别是,我在 Windows 机器上使用 Maven 构建之前运行 vcvars32.bat。这是我收到的错误:

main.obj : error LNK2019: unresolved external symbol "public: int __thiscall 
Calculator::add(int,int)" (?add@Calculator@@QAEHHH@Z) referenced in function
_main executable.exe : fatal error LNK1120: 1 unresolved externals

NAR 插件吐出的链接器命令如下所示:

link /MANIFEST /NOLOGO /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /OUT:executable.exe
C:\dev\Projects\trunk\executable\target\nar\obj\x86-Windows-msvc\main.obj

我希望它应该列出由我的共享库模块生成的 DLL,但它不在那里。 DLL 的 NAR 被解压到可执行文件的目标目录中,正如它应该的那样。

任何有关为 Windows 配置 NAR 插件的帮助将不胜感激。或者,显示如何正确执行链接器的命令行也很有用,这样我就可以回填 NAR 配置来实现它。谢谢。

我的共享库模块:

Calculator.h

#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator {
public:
    int add(int first, int second);
};

#endif

Calculator.cc

#include "Calculator.h"

int Calculator::add(int first, int second) {
    return first + second;
}

pom.xml(片段):

<groupId>com.mycompany</groupId>
<artifactId>library</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>

...

<plugin>
    <artifactId>maven-nar-plugin</artifactId>
    <version>2.1-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <libraries>
            <library>
                <type>shared</type>
            </library>
        </libraries>
    </configuration>
</plugin>

我的可执行模块:

main.cc< /em>

#include <iostream>
#include "Calculator.h"

int main() {
    Calculator calculator;
    std::cout << calculator.add(2, 5) << std::endl;
}

pom.xml(片段)

<groupId>com.mycompany</groupId>
<artifactId>executable</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>

<dependency>
    <groupId>com.mycompany</groupId>
    <artifactId>library</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <type>nar</type>
</dependency>

...

<plugin>
    <artifactId>maven-nar-plugin</artifactId>
    <version>2.1-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <libraries>
            <library>
                <type>executable</type>
            </library>
        </libraries>
    </configuration>
</plugin>

I am trying to build a very simple C++ program using the Maven NAR plugin. I've set up a Maven module for building a shared library, and another for linking in the library and building an executable that uses it. Building on a Mac works great and I can run the program. Unfortunately, building on Windows (XP) with MS Visual C++ (free version) fails with a linker error. The only difference in configurations between the two machines (other than OS and compiler) is that I run vcvars32.bat before building with Maven on the Windows machine. Here's the error I am getting:

main.obj : error LNK2019: unresolved external symbol "public: int __thiscall 
Calculator::add(int,int)" (?add@Calculator@@QAEHHH@Z) referenced in function
_main executable.exe : fatal error LNK1120: 1 unresolved externals

The linker command spit out by the NAR plugin looks like this:

link /MANIFEST /NOLOGO /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /OUT:executable.exe
C:\dev\Projects\trunk\executable\target\nar\obj\x86-Windows-msvc\main.obj

I expect it should have the DLL generated by my shared library module listed, but its not there. The DLL's NAR is unpacked in the executable's target directory, as it should be.

Any help in configuring the NAR plugin for Windows would be appreciated. Alternately a command line showing how to properly execute the linker would be useful so I can backfill the NAR configuration to achieve it. Thanks.

My shared library module:

Calculator.h

#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator {
public:
    int add(int first, int second);
};

#endif

Calculator.cc

#include "Calculator.h"

int Calculator::add(int first, int second) {
    return first + second;
}

pom.xml (snippets):

<groupId>com.mycompany</groupId>
<artifactId>library</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>

...

<plugin>
    <artifactId>maven-nar-plugin</artifactId>
    <version>2.1-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <libraries>
            <library>
                <type>shared</type>
            </library>
        </libraries>
    </configuration>
</plugin>

My executable module:

main.cc

#include <iostream>
#include "Calculator.h"

int main() {
    Calculator calculator;
    std::cout << calculator.add(2, 5) << std::endl;
}

pom.xml (snippets)

<groupId>com.mycompany</groupId>
<artifactId>executable</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>nar</packaging>

<dependency>
    <groupId>com.mycompany</groupId>
    <artifactId>library</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <type>nar</type>
</dependency>

...

<plugin>
    <artifactId>maven-nar-plugin</artifactId>
    <version>2.1-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <libraries>
            <library>
                <type>executable</type>
            </library>
        </libraries>
    </configuration>
</plugin>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜吻♂芭芘 2024-10-23 15:41:31

回答我自己的问题。

我的一位同事深入研究了他大脑中更阴暗的部分,并说他记得需要类似“dicklespeck”的东西。这听起来很奇怪,所以我把它放在“如果其他方法都失败了,我会查一下”的桶中。在所有其他方法都失败后,我又回来了,并用谷歌搜索了各种拼写,结果表明他是正确的。如果我将这个令人厌恶的内容添加到我的类声明中:

__declspec(dllexport)

DLL 成功链接到可执行文件。

因此,像这样“修复”计算器头文件就是解决方案:

#ifndef CALCULATOR_H
#define CALCULATOR_H

class __declspec(dllexport) Calculator {
public:
    int add(int first, int second);
};

#endif

呸!我可以#define 为非 Windows 构建去掉这个东西,但仍然 - 恶心!

有人请告诉我这不是唯一的解决方案。

Answering my own question.

A colleague of mine dug into the murkier recesses of his brain and said he recalled something like "dicklespeck" being needed. That sounded bizarre so I put it in the "if all else fails I'll look that up" bucket. After all else failed, I came back to it and Googled various spellings which revealed that he was correct. If I add this abomination to my class declaration:

__declspec(dllexport)

The DLL successfully links with the executable.

So "fixing" the Calculator header file like so is the solution:

#ifndef CALCULATOR_H
#define CALCULATOR_H

class __declspec(dllexport) Calculator {
public:
    int add(int first, int second);
};

#endif

Yuck! I can #define that thing away for non-windows builds, but still - yuck!

Someone please tell me this isn't the only solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文