【问题标题】:How to link a DLL to my main project? (Getting unresolved external error)如何将 DLL 链接到我的主项目? (得到未解决的外部错误)
【发布时间】:2023-03-16 10:52:01
【问题描述】:

我仍在学习 C++ 语言的一些用途。

所以,我决定创建我的库(动态)并将其导入到我的项目中。 我已经按照互联网上的教程的一些步骤进行操作,但是我遇到了未解决的外部错误...

让我去DLL项目:

文件1.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 文件)。

使用以下详细信息启动了一个新的控制台应用程序:

文件1.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++ builder XE7.

从现在开始,非常感谢。

【问题讨论】:

    标签: c++ dll c++builder dynamic-linking c++builder-xe7


    【解决方案1】:

    您使用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
    

    文件1.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;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-11
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 2020-04-30
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多