【问题标题】:How do you build a DLL file containing multiple source files, with functions to be exported in multiple files?如何构建包含多个源文件的 DLL 文件,并在多个文件中导出函数?
【发布时间】:2012-11-28 11:10:13
【问题描述】:

一些上下文:我正在尝试将 Lua 源代码构建为 DLL(学习目的!),在 Windows 上使用 Pelles C(使用 C)。主要针对 x64,如果这很重要的话。

通过在我的 Pelles C 中使用 DLL 向导,它会自动生成带有示例函数和 DLLMain.h 的 DLLMain.c。这很好,除了现在我不确定如何导出所有其他 lua 函数。只需添加 Lua 网站告诉我的所有源文件(这太简单了,不可能工作,但你永远不知道......)然后用适当的 #defines 构建它只是导出示例函数,我'已使用 polib.exe 检查过:

一些来源:

自动生成的 DLL main:

/****************************************************************************
 *                                                                          *
 * File    : dllmain.c                                                      *
 *                                                                          *
 * Purpose : Generic Win32 Dynamic Link Library (DLL).                      *
 *                                                                          *
 * History : Date      Reason                                               *
 *           00/00/00  Created                                              *
 *                                                                          *
 ****************************************************************************/

#define WIN32_LEAN_AND_MEAN  /* speed up */
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <tchar.h>

/*
 * Include our "interface" file and define a symbol
 * to indicate that we are *building* the DLL.
 */
#define _LUADLLTE_
#include "LUADLLTE.h"
                            //!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!
#include "lua.h"            //I added these 3. Do these not go here?
#include "lauxlib.h"        //They are the 3 headers that every Lua tutorial
#include "lualib.h"         //includes.
                            //~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~

/****************************************************************************
 *                                                                          *
 * Function: DllMain                                                        *
 *                                                                          *
 * Purpose : DLL entry and exit procedure.                                  *
 *                                                                          *
 * History : Date      Reason                                               *
 *           00/00/00  Created                                              *
 *                                                                          *
 ****************************************************************************/

BOOL APIENTRY DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            /*
             * Microsoft says:
             *
             * blah comments blah
             */
            break;

        case DLL_THREAD_ATTACH:
            /*
             * Microsoft says:
             *
             * blah blah
             */
            break;

        case DLL_THREAD_DETACH:
            /*
             * blah blah
             */
            break;

        case DLL_PROCESS_DETACH:
            /*
             * blah
             */
            break;
    }

    /* Return success */
    return TRUE;
}

/****************************************************************************
 *                                                                          *
 * Function: SampleFunction                                                 *
 *                                                                          *
 * Purpose : Sample function which does nothing useful.                     *
 *                                                                          *
 * History : Date      Reason                                               *
 *           00/00/00  Created                                              *
 *                                                                          *
 ****************************************************************************/

LUADLLTEAPI int WINAPI SampleFunction(int a, int b)
{
    /* TODO: Replace with your own code */
    return a * b;
}

自动生成的标题:

// INCLUDE FILE generated by "Pelles C for Windows, version 3.00".

#ifndef _LUADLLTE_H
#define _LUADLLTE_H

#ifdef _LUADLLTE_
#define LUADLLTEAPI  __declspec(dllexport)
                           //!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!
#define LUA_BUILD_AS_DLL   //I added these 3 defines as well.
#define LUA_CORE           //See next source excerpt for the 
#define LUA_LIB            //reasoning.
                           //!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!~~~!!!
#else
#define LUADLLTEAPI  __declspec(dllimport)
#endif /* _LUADLLTE_ */

#ifndef WINAPI
#define WINAPI  __stdcall
#endif

LUADLLTEAPI int WINAPI SampleFunction(int, int);

#endif /* _LUADLLTE_H */

luaconf.h,相关(我认为?)部分:

/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all auxiliary library functions.
@@ LUAMOD_API is a mark for all standard library opening functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL)   /* { */

#if defined(LUA_CORE) || defined(LUA_LIB)   /* { */
#define LUA_API __declspec(dllexport)
#else                       /* }{ */
#define LUA_API __declspec(dllimport)
#endif                      /* } */

#else               /* }{ */

#define LUA_API     extern

#endif              /* } */


/* more often than not the libs go together with the core */
#define LUALIB_API  LUA_API
#define LUAMOD_API  LUALIB_API

这些定义决定了如何构建 lua api 调用,具体取决于定义的符号。这就是我在头文件中添加它们的原因。

我可以将函数添加到自动生成的 header/c 文件中,它们将根据 polib.exe 显示在 lib 中。这让我认为我需要找到每个函数调用并将其移动到 dllmain 文件中,但这听起来不是最佳方式。

这些来源并没有真正回答这个问题:

How do you merge multiple static linked libraries into a single dll given each static lib defines exported functionality (vc++ 2008)?

would appreciate for some one pointing me to good DLL tutorial

~我找到的教程都是单文件DLL教程。

Compiling & Decompiling dll files

~这个接近了,但没有我需要的答案。

~Lua 网站和build documentation 在 Windows 方面不是很清楚/具体。

我完全有可能遗漏了一些非常明显的东西。我首先通过单源/单头文件 DLL 来感受它,现在我想尝试编译 Lua(我实际上想在某个时候尝试了解它)。让我知道这个问题是否有点令人费解。我认为这是我的 DLL 知识的问题,而不是 Lua,所以我的问题是:

如何构建包含多个源文件的 DLL 文件,并在多个文件中导出函数?

PS:我缺少关于这个主题的哪些基本知识,如果这可能是根本原因?另外,抱歉篇幅太长……刚刚注意到……

编辑:已解决!谢谢 Mud。

方法:在 Pelles C 中,转到 Project Options... -> Compiler 选项卡,然后在 Define preprocessor symbols 行下输入 LUA_BUILD_AS_DLL LUA_LIB(或 LUA_BUILD_AS_DLL LUA_CORELUA_BUILD_AS_DLL LUA_CORE LUA_LIB)。

【问题讨论】:

    标签: dll lua


    【解决方案1】:

    您要导出的所有 Lua API 函数都以 LUA_API 为前缀。如您所述,要正确定义 LUA_API(对于 Visual Studio、GCC 等),您只需定义 LUA_BUILD_AS_DLL 和 LUA_LIB。

    但是,您在头文件中定义它们,因此这些定义仅存在于包含该头文件的文件中——即没有一个 Lua 文件包含您的头文件。

    您需要在 project-settings/makefile/whatever 中定义这些符号,以便在编译 Lua 源代码期间定义它们。

    【讨论】:

    • 伙计,就好像我对这么简单的疏忽大意了那么多。你真是个天才。 :D 编辑:现在来测试我是否真的可以使用它!
    • 一个简单的问题:其他一切都合理正确吗?我可以为 3 个 Lua 头文件添加 3 个包含 DLLmain 吗?
    • 您只需要在给定模块中包含您实际使用的函数/类型的标题。您目前没有使用它们,因此您可以删除所有三个。如果您要向 DLL 中添加一些您自己的函数,您将使用 lua.h(包含主要的 Lua 类型,如 lua_State 和核心 Lua API 例程,如 lua_pushnumber)和 lauxlib.h(包含辅助例程比如luaL_checknumber)。您将不需要lualib.h - 该标头将由正在加载 Lua DLL 的 主机 应用程序使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2011-06-13
    • 1970-01-01
    相关资源
    最近更新 更多