简体   繁体   English

如何将DLL链接到我的主项目? (获取未解决的外部错误)

[英]How to link a DLL to my main project? (Getting unresolved external error)

I'm still learning some uses of the C++ language. 我仍在学习C ++语言的一些用法。

So, I decided to create my library (dynamic) and import it to my project. 因此,我决定创建我的库(动态)并将其导入到我的项目中。 I've followed some steps of a tutorial in the internet, but I aways have the error of unresolved external... 我已经按照互联网上教程的一些步骤进行操作,但是我却遇到了无法解决的外部错误……

Let me go to the DLL project: 让我转到DLL项目:

File1.cpp: 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: 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);
    };
}

Result: Succeedfully compilled (Got Project1.dll and Project1.lib files). 结果:成功编译(获得Project1.dll和Project1.lib文件)。

Started a new console application with the following details: 使用以下详细信息启动了新的控制台应用程序:

File1.cpp: 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.: PS:

I also tried without the LoadLibrary() function. 我也尝试不使用LoadLibrary()函数。

Something I also tried: ->Added the .lib, .h, .dll files in the project; 我还尝试了一些方法:->在项目中添加了.lib,.h,.dll文件;

->Added the .lib, .h, .dll files in the same folder of the console application folder; ->在控制台应用程序文件夹的同一文件夹中添加了.lib,.h,.dll文件;

->Added the .lib, .h, .dll files in the references of theproject (C++ shared options). ->在项目的引用中添加了.lib,.h,.dll文件(C ++共享选项)。

What I think: The MathFuncsDLL.h is being read by the compiler, once it finds the functions/classes when I'm writing the code of the main program. 我的想法:一旦我在编写主程序的代码时找到了函数/类,编译器就会读取MathFuncsDLL.h。

Problems I got untill now: 直到现在我遇到的问题:

[ilink32 Error] Error: Unresolved external 'MathFuncs::MyMathFuncs::Add(double, double)' referenced from C:\\USERS\\MAURO\\DESKTOP\\PROJETO\\WIN32\\DEBUG\\FILE1.OBJ [ilink32错误]错误:从C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解决的外部'MathFuncs :: MyMathFuncs :: Add(double,double)'

[ilink32 Error] Error: Unresolved external 'MathFuncs::MyMathFuncs::Subtract(double, double)' referenced from C:\\USERS\\MAURO\\DESKTOP\\PROJETO\\WIN32\\DEBUG\\FILE1.OBJ [ilink32错误]错误:从C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解决的外部'MathFuncs :: MyMathFuncs :: Subtract(double,double)'

[ilink32 Error] Error: Unresolved external 'MathFuncs::MyMathFuncs::Multiply(double, double)' referenced from C:\\USERS\\MAURO\\DESKTOP\\PROJETO\\WIN32\\DEBUG\\FILE1.OBJ [ilink32错误]错误:从C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解决的外部'MathFuncs :: MyMathFuncs :: Multiply(double,double)'

[ilink32 Error] Error: Unresolved external 'MathFuncs::MyMathFuncs::Divide(double, double)' referenced from C:\\USERS\\MAURO\\DESKTOP\\PROJETO\\WIN32\\DEBUG\\FILE1.OBJ [ilink32错误]错误:从C:\\ USERS \\ MAURO \\ DESKTOP \\ PROJETO \\ WIN32 \\ DEBUG \\ FILE1.OBJ引用的未解决的外部'MathFuncs :: MyMathFuncs :: Divide(double,double)'

Details of the compiler: -> C++ builder XE7. 编译器的详细信息:-> C ++构建器XE7。

Since now, thanks a lot. 从现在开始,非常感谢。

You use of LoadLibrary() is wrong and useless. 您使用LoadLibrary()是错误的并且没有用。 You are not passing the returned module handle to GetProcAddress() to load the DLL functions dynamically. 您没有将返回的模块句柄传递给GetProcAddress()来动态加载DLL函数。 So remove the call to LoadLibrary() . 因此,删除对LoadLibrary()的调用。

Your console code is trying to link statically to the DLL functions. 您的控制台代码正在尝试静态链接到DLL函数。 To resolve the references, you need to add the DLL's .lib file to your console project, either in the Project Manager, or via a #pragma comment(lib, Project1.lib) statement in your code. 若要解析引用,您需要在项目管理器中或通过代码中的#pragma comment(lib, Project1.lib)语句将DLL的.lib文件添加到控制台项目中。 It is not enough for the .lib file to be present in the console project's folder. .lib文件不足在控制台项目的文件夹中。

That being said, your DLL should not be trying to export namespaced class static functions to begin with. 话虽这么说,您的DLL不应尝试从名称空间开始导出静态类。 Export flat C-style standalone functions instead. 而是导出平面C风格的独立函数。 Your header can provide a namespaced wrapper class for use in C++, just don't export it. 您的标头可以提供用于C ++中的命名空间包装器类,只是不要导出它。

It is also not safe to throw exceptions (especially class-based exceptions) over the DLL boundary, either. 在DLL边界上抛出异常(尤其是基于类的异常)也不安全。 You need to get rid of that completely. 您需要完全摆脱它。 In the case of Divide() , either make the caller validate that it never passes b=0 , or else change the signature of Divide() to return a bool indicating success/failure and use a separate output parameter to return the division result. Divide()的情况下,要么使调用者验证它从未通过b=0 ,要么更改Divide()的签名以返回表示成功/失败的bool值,并使用单独的输出参数返回除法结果。

Try something more like this: 尝试更多类似这样的方法:

MathFuncsDll.cpp: 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: 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: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM