Как связать DLL с моим основным проектом? (Получение неразрешенной внешней ошибки)

Я все еще изучаю некоторые применения языка C ++.

Итак, я решил создать свою библиотеку (динамическую) и импортировать ее в свой проект.
Я следовал за некоторыми шагами учебника в Интернете, но у меня всегда есть ошибка неразрешенного внешнего …

Позвольте мне перейти к проекту DLL:

File1.cpp:

#include "MathFuncsDll.h"#include <stdexcept>

using namespace std;

namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b)
{
return a + b;
}

double MyMathFuncs::Subtract(double a, double b)
{
return a - b;
}

double MyMathFuncs::Multiply(double a, double b)
{
return a * b;
}

double MyMathFuncs::Divide(double a, double b)
{
if (b == 0)
{
throw invalid_argument("b cannot be zero!");
}

return a / b;
}
}

MathFuncs.h:

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport)
#else
#define MATHFUNCSDLL_API __declspec(dllimport)
#endif

namespace MathFuncs
{
// This class is exported from the MathFuncsDll.dll
class MyMathFuncs
{
public:
// Returns a + b
static MATHFUNCSDLL_API double Add(double a, double b);

// Returns a - b
static MATHFUNCSDLL_API double Subtract(double a, double b);

// Returns a * b
static MATHFUNCSDLL_API double Multiply(double a, double b);

// Returns a / b
// Throws const std::invalid_argument& if b is 0
static MATHFUNCSDLL_API double Divide(double a, double b);
};
}

Результат: успешно скомпилирован (получил файлы Project1.dll и Project1.lib).

Запустил новое консольное приложение со следующими данными:

File1.cpp:

// MyExecRefsDll.cpp
// compile with: /EHsc /link MathFuncsDll.lib

#include <iostream>
#include <Windows.h>

#include "MathFuncsDll.h"
using namespace std;

int main()
{
double a = 7.4;
int b = 99;

try {

LoadLibrary(TEXT("MathFuncsDll.dll")); // Also tried without TEXT();

cout << "a + b = " <<
MathFuncs::MyMathFuncs::Add(a, b) << endl;
cout << "a - b = " <<
MathFuncs::MyMathFuncs::Subtract(a, b) << endl;
cout << "a * b = " <<
MathFuncs::MyMathFuncs::Multiply(a, b) << endl;
cout << "a / b = " <<
MathFuncs::MyMathFuncs::Divide(a, b) << endl;

try
{
cout << "a / 0 = " <<
MathFuncs::MyMathFuncs::Divide(a, 0) << endl;
}
catch (const invalid_argument &e)
{
cout << "Caught exception: " << e.what() << endl;
}
}
catch (...){
cout << "Problem when loading dll file" << endl;
}

system("pause");

return 0;
}

PS .:

Я тоже пробовал без LoadLibrary() функция.

Что-то я тоже попробовал:
-> Добавлены файлы .lib, .h, .dll в проект;

-> Добавлены файлы .lib, .h, .dll в ту же папку в папке консольного приложения;

-> Добавлены файлы .lib, .h, .dll в ссылки проекта (общие параметры C ++).

Что я думаю: MathFuncsDLL.h читается компилятором, как только он находит функции / классы, когда я пишу код основной программы.

Проблемы, которые я получил до сих пор:

[ilink32 Ошибка] Ошибка: Неразрешенный внешний файл ‘MathFuncs :: MyMathFuncs :: Add (double, double)’, на который ссылается C: \ USERS \ MAURO \ DESKTOP \ PROJETO \ WIN32 \ DEBUG \ FILE1.OBJ

[ilink32 Error] Ошибка: Неразрешенный внешний файл ‘MathFuncs :: MyMathFuncs :: Subtract (double, double)’, указанный в C: \ USERS \ MAURO \ DESKTOP \ PROJETO \ WIN32 \ DEBUG \ FILE1.OBJ

[ilink32 Ошибка] Ошибка: Неразрешенный внешний файл ‘MathFuncs :: MyMathFuncs :: Multiply (double, double)’, указанный в C: \ USERS \ MAURO \ DESKTOP \ PROJETO \ WIN32 \ DEBUG \ FILE1.OBJ

[ilink32 Ошибка] Ошибка: Неразрешенный внешний файл ‘MathFuncs :: MyMathFuncs :: Divide (double, double)’, указанный в C: \ USERS \ MAURO \ DESKTOP \ PROJETO \ WIN32 \ DEBUG \ FILE1.OBJ

Детали компилятора:
-> C ++ Builder XE7.

С тех пор спасибо большое.

0

Решение

Вы используете LoadLibrary() неправильно и бесполезно. Вы не передаете дескриптор возвращенного модуля GetProcAddress() загружать функции DLL динамически. Так что уберите звонок LoadLibrary(),

Ваш консольный код пытается статически связать с функциями DLL. Чтобы разрешить ссылки, вам нужно добавить DLL .lib файл в консольный проект, либо в диспетчере проектов, либо через #pragma comment(lib, Project1.lib) Заявление в вашем коде. Недостаточно, чтобы файл .lib присутствовал в папке консольного проекта.

При этом ваша DLL не должна пытаться экспортировать статические функции класса пространства имен для начала. Вместо этого экспортируйте отдельные функции в стиле C. Ваш заголовок может предоставить класс-оболочку пространства имен для использования в C ++, просто не экспортируйте его.

Также небезопасно выбрасывать исключения (особенно исключения на основе классов) через границу DLL. Вы должны полностью избавиться от этого. В случае Divide()либо сделайте так, чтобы вызывающий абонент подтвердил, что он никогда не проходит b=0или измените подпись Divide() вернуть bool указывает на успех / неудачу и использует отдельный выходной параметр для возврата результата деления.

Попробуйте что-то вроде этого:

MathFuncsDll.cpp:

#define MATHFUNCSDLL_EXPORTS
#include "MathFuncsDll.h"
double MathFuncs_Add(double a, double b)
{
return a + b;
}

double MathFuncs_Subtract(double a, double b)
{
return a - b;
}

double MathFuncs_Multiply(double a, double b)
{
return a * b;
}

double MathFuncs_Divide(double a, double b)
{
return a / b;
}
/* alternatively:
bool MathFuncs_Divide(double a, double b, double *result)
{
if (b == 0) return false;
if (result) *result = a / b;
return true;
}
*/

MathFuncsDll.h:

#ifndef MathFuncsDllH
#define MathFuncsDllH

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport)
#else
#define MATHFUNCSDLL_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

// Returns a + b
MATHFUNCSDLL_API double MathFuncs_Add(double a, double b);

// Returns a - b
MATHFUNCSDLL_API double MathFuncs_Subtract(double a, double b);

// Returns a * b
MATHFUNCSDLL_API double MathFuncs_Multiply(double a, double b);

// Returns a / b
MATHFUNCSDLL_API double MathFuncs_Divide(double a, double b);
// alternatively: bool MathFuncs_Divide(double a, double b, double *result);

#ifdef __cplusplus
}

#include <stdexcept>

namespace MathFuncs
{
class MyMathFuncs
{
public:
static Add(double a, double b) { return MathFuncs_Add(a, b); }
static double Subtract(double a, double b) { return MathFuncs_Subtract(a, b); }
static double Multiply(double a, double b) { return MathFuncs_Multiply(a, b); }
static double Divide(double a, double b)
{
if (b == 0)
throw std::invalid_argument("b cannot be zero!");
return MathFuncs_Divide(a, b);
/* alternatively:
double result;
if (!MathFuncs_Divide(a, b, &result))
throw std::invalid_argument("b cannot be zero!");
return result;
*/
}
};
}
#endif

#endif

File1.cpp:

#include <windows.h>
#include <iostream>

// if you don't add the DLL .lib file to the project using the Project Manager,
// uncomment this statement ...  either way, you really should rename your DLL
// project to something more meaningful then "Project1" ...
// #pragma comment(lib, "Project1.lib")

#include "MathFuncsDll.h"
int main()
{
double a = 7.4;
int b = 99;

try
{
std::cout << "a + b = " << MathFuncs::MyMathFuncs::Add(a, b) << std::endl;
std::cout << "a - b = " << MathFuncs::MyMathFuncs::Subtract(a, b) << std::endl;
std::cout << "a * b = " << MathFuncs::MyMathFuncs::Multiply(a, b) << std::endl;
std::cout << "a / b = " << MathFuncs::MyMathFuncs::Divide(a, b) << std::endl;

try
{
std::cout << "a / 0 = " << MathFuncs::MyMathFuncs::Divide(a, 0) << std::endl;
}
catch (const std::invalid_argument &e)
{
std::cout << "Caught exception: " << e.what() << std::endl;
}
}
catch (...)
{
std::cout << "Problem when loading dll file" << std::endl;
}

system("pause");

return 0;
}
1

Другие решения

Других решений пока нет …