40

我在 VS 2008 中有一个解决方案,其中包含 2 个项目。一个是用 C++ 编写的 DLL,另一个是从空白项目创建的简单 C++ 控制台应用程序。我想知道如何从应用程序调用 DLL 中的函数。

假设我从一个空白 C++ 项目开始,并且我想调用一个名为int IsolatedFunction(int someParam)

我怎么称呼它?

4

7 回答 7

21

有很多方法可以做到这一点,但我认为最简单的选择之一是在链接时将应用程序链接到 DLL,然后使用定义文件来定义要从 DLL 导出的符号。

警告:定义文件方法最适合未修饰的符号名称。如果要导出修饰符号,那么最好不要使用定义文件方法。

这是一个关于如何完成的简单示例。

第 1 步:export.h文件中定义函数。

int WINAPI IsolatedFunction(const char *title, const char *test);

第 2 步:export.cpp文件中定义函数。

#include <windows.h>

int WINAPI IsolatedFunction(const char *title, const char *test)
{
    MessageBox(0, title, test, MB_OK);
    return 1;
}

第 3 步:在export.def定义文件中将函数定义为导出。

EXPORTS    IsolatedFunction          @1

第 4 步:创建一个 DLL 项目并将export.cppexport.def文件添加到该项目中。构建这个项目将创建一个export.dll和一个export.lib文件。

以下两个步骤在链接时链接到 DLL。如果您不想在链接时定义入口点,请忽略接下来的两个步骤并使用LoadLibraryGetProcAddress在运行时加载函数入口点。

第 5 步:通过将export.lib文件添加到项目中来创建一个测试应用程序项目以使用该 dll。export.dll文件复制到与测试控制台可执行文件相同的位置。

第 6 步:从 Test 应用程序中调用IsolatedFunction函数,如下所示。

#include "stdafx.h"

// get the function prototype of the imported function
#include "../export/export.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    // call the imported function found in the dll
    int result = IsolatedFunction("hello", "world");

    return 0;
}
于 2009-02-12T04:36:58.533 回答
9

也可以从dll导出函数,从exe导入,一开始比较棘手,但最后比调用LoadLibrary/GetProcAddress容易得多。请参阅MSDN

使用 VS 向导创建项目时,dll 中有一个复选框,可让您导出函数。

然后,在 exe 应用程序中,您只需 #include 来自 dll 的具有正确定义的标头,并将 dll 项目作为依赖项添加到 exe 应用程序。

如果您想进一步调查这一点,请检查其他问题。使用 dllexport 从 DLL 导出函数

于 2009-02-11T23:50:41.653 回答
6

您可以使用 LoadLibrary/GetProcAddress 路线(正如 Harper 在他的回答中提到的,这里再次链接到运行时动态链接 MSDN 示例),或者您可以将控制台应用程序链接到从 DLL 项目生成的 .lib 并包含 hea .h 文件,其中包含您的函数声明(如加载时动态链接 MSDN 示例中所述)

在这两种情况下,您都需要确保您的 DLL 导出您想要正确调用的函数。最简单的方法是在函数声明中使用 __declspec(dllexport)(如创建简单的动态链接库 MSDN 示例中所示),尽管您也可以通过 DLL 项目中的相应 .def 文件来实现。

有关 DLL 主题的更多信息,您应该浏览MSDN About Dynamic-Link Libraries主题。

于 2009-02-11T23:52:22.053 回答
6

以下是所需的 5 个步骤:

  1. 声明函数指针
  2. 加载库
  3. 获取程序地址
  4. 将其分配给函数指针
  5. 使用函数指针调用函数

您可以在http://www.softwareandfinance.com/Visual_CPP/DLLDynamicBinding.html找到逐步的 VC++ IDE 屏幕截图

这是代码片段:

int main()
{
/***
__declspec(dllimport) bool GetWelcomeMessage(char *buf, int len); // used for static binding
 ***/
    typedef bool (*GW)(char *buf, int len);

    HMODULE hModule = LoadLibrary(TEXT("TestServer.DLL"));
    GW GetWelcomeMessage = (GW) GetProcAddress(hModule, "GetWelcomeMessage");

    char buf[128];
    if(GetWelcomeMessage(buf, 128) == true)
        std::cout << buf;
        return 0;
}
于 2013-10-10T22:04:41.137 回答
1

可能有用:https ://www.codeproject.com/Articles/6299/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part-4

对于上面带有“GetWelcomeMessage”的示例,如果在调用导入的函数后出现错误,您可能需要在函数名称之前的 typedef 字段中指定“__stdcall”。

于 2020-09-11T06:49:46.313 回答
0

假设您正在讨论 DLL 的动态运行时加载,您正在寻找 LoadLibrary 和 GetProAddress。MSDN上有一个例子。

于 2009-02-11T23:37:49.250 回答
0

当创建 DLL 时,通常会自动创建一个导入库,您应该使用链接到程序的头文件以及头文件来调用它,但如果没有,您可以手动调用 Windows 函数,如LoadLibraryGetProcAddress以使其工作。

于 2009-02-11T23:54:06.107 回答