![](/img/trans.png)
[英]How do I link a DLL to my project? error LNK2019: unresolved external symbol
[英]How to link a DLL to my main project? (Getting unresolved external error)
我仍在學習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錯誤]錯誤:從C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解決的外部'MathFuncs :: MyMathFuncs :: Add(double,double)'
[ilink32錯誤]錯誤:從C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解決的外部'MathFuncs :: MyMathFuncs :: Subtract(double,double)'
[ilink32錯誤]錯誤:從C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解決的外部'MathFuncs :: MyMathFuncs :: Multiply(double,double)'
[ilink32錯誤]錯誤:從C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解決的外部'MathFuncs :: MyMathFuncs :: Divide(double,double)'
編譯器的詳細信息:-> C ++構建器XE7。
從現在開始,非常感謝。
您使用LoadLibrary()
是錯誤的並且沒有用。 您沒有將返回的模塊句柄傳遞給GetProcAddress()
來動態加載DLL函數。 因此,刪除對LoadLibrary()
的調用。
您的控制台代碼正在嘗試靜態鏈接到DLL函數。 若要解析引用,您需要在項目管理器中或通過代碼中的#pragma comment(lib, Project1.lib)
語句將DLL的.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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.