Связывание с DLL в Windows с помощью плагина Maven NAR
Я пытаюсь создать очень простую программу на C++, используя плагин Maven NAR. Я установил модуль Maven для создания общей библиотеки, а другой - для связи в библиотеке и создания исполняемого файла, который ее использует. Сборка на Mac прекрасно работает, и я могу запустить программу. К сожалению, сборка на Windows (XP) с MS Visual C++ (бесплатная версия) завершается с ошибкой компоновщика. Единственное различие в конфигурации между двумя компьютерами (кроме ОС и компилятора) заключается в том, что я запускаю vcvars32.bat перед сборкой с Maven на компьютере с Windows. Вот ошибка, которую я получаю:
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, сгенерированная моим модулем общей библиотеки, но ее там нет. NAR библиотеки DLL распаковывается в целевой каталог исполняемого файла, как и должно быть.
Любая помощь в настройке плагина NAR для Windows будет принята с благодарностью. В качестве альтернативы была бы полезна командная строка, показывающая, как правильно выполнить компоновщик, чтобы я мог заполнить конфигурацию 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
#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>
1 ответ
Отвечая на мой собственный вопрос.
Мой коллега вкопался в темные ниши своего мозга и сказал, что вспомнил, что нужно что-то вроде "гребешка". Это звучало странно, поэтому я положил его в корзину "если ничего не получится, я посмотрю". После того, как все остальное не удалось, я вернулся к нему и погуглил различные варианты написания, которые показали, что он был прав. Если я добавлю эту мерзость в мое объявление класса:
__declspec(dllexport)
DLL успешно связывается с исполняемым файлом.
Итак, "исправление" заголовочного файла калькулятора выглядит так:
#ifndef CALCULATOR_H
#define CALCULATOR_H
class __declspec(dllexport) Calculator {
public:
int add(int first, int second);
};
#endif
Тьфу! Я могу #define
эта штука для сборок не-окон, но все же - блин!
Кто-то, пожалуйста, скажите мне, что это не единственное решение.