【DCS开源项目】—— Lua 如何调用 DLL、DLL 与 DCS World 的交互

发布于:2025-06-22 ⋅ 阅读:(19) ⋅ 点赞:(0)



1. Lua 调用 C++ DLL 的机制

入口与注册

  • 在 DCS World 的 Mods 目录下,Olympus 以插件形式加载,Lua 脚本(如 entry.lua)声明插件并初始化。
  • 主要 Lua 脚本(如 OlympusCommand.lua)负责加载 DLL,并通过 require("olympus")package.loadlib 方式调用 C++ 导出的 Lua C API。
entry.lua
local self_ID = "DCS-Olympus"

declare_plugin(self_ID,
{
   
	image		 = "Olympus.png",
	installed	 = true, -- if false that will be place holder , or advertising
	dirName		 = current_mod_path,
	binaries	 =
	{
   
--		'Olympus',
	},
	load_immediately = true,

	displayName	 = "Olympus",
	shortName	 = "Olympus",
	fileMenuName = "Olympus",

	version		 = "{
   {OLYMPUS_VERSION_NUMBER}}",
	state		 = "installed",
	developerName= "DCS Refugees 767 squadron",
	info		 = _("DCS Olympus is a mod for DCS World. It allows users to spawn, control, task, group, and remove units from a DCS World server using a real-time map interface, similarly to Real Time Strategy games. The user interface also provides useful informations units, like loadouts, fuel, tasking, and so on. In the future, more features for DCS World GCI and JTAC will be available."),

	Skins	=
	{
   
		{
   
			name	= "Olympus",
			dir		= "Theme"
		},
	},

	Options =
	{
   
		{
   
			name		= "Olympus",
			nameId		= "Olympus",
			dir			= "Options",
			CLSID		= "{Olympus-options}"
		},
	},
})

plugin_done()

DLL 导出接口

  • C++ 侧通过 extern "C" DllExport int luaopen_olympus(lua_State *L) 导出模块初始化函数,供 Lua 加载。
  • 在 olympus.cpp 中,注册了一系列 Lua 可调用的 C 函数(如 onSimulationStartonSimulationFramesetUnitsData 等),这些函数会被 Lua 脚本直接调用。
onSimulationStart代码
//olympus.cpp

static int onSimulationStart(lua_State* L)
{
   
    LogInfo(L, "Trying to load core.dll from " + modPath);
    SetDllDirectoryA(modPath.c_str());

    setLogDirectory(modPath);

    log("onSimulationStart callback called successfully");

    string dllLocation = modPath + "\\core.dll";
    
    log("Loading core.dll");
    hGetProcIDDLL = LoadLibrary(to_wstring(dllLocation).c_str());

    if (!hGetProcIDDLL) {
   
        LogError(L, "Error loading core DLL");
        goto error;
    }

    log("Core DLL loaded successfully");

    coreInit = (f_coreInit)GetProcAddress(hGetProcIDDLL, "coreInit");
    if (!coreInit) 
    {
   
        LogError(L, "Error getting coreInit ProcAddress from DLL");
        goto error;
    }

    coreDeinit = (f_coreDeinit)GetProcAddress(hGetProcIDDLL, "coreDeinit");
    if (!coreDeinit)
    {
   
        LogError(L, "Error getting coreDeinit ProcAddress from DLL");
        goto error;
    }

    coreFrame = (f_coreFrame)GetProcAddress(hGetProcIDDLL, "coreFrame");
    if (!coreFrame) 
    {
   
        LogError(L, "Error getting coreFrame ProcAddress from DLL");
        goto error;
    }

    coreUnitsData = (f_coreUnitsData)GetProcAddress(hGetProcIDDLL, "coreUnitsData");
    if (!coreUnitsData)
    {
   
        LogError(L, "Error getting coreUnitsData ProcAddress from DLL");
        goto error;
    }

    coreWeaponsData = (f_coreWeaponsData)GetProcAddress(hGetProcIDDLL, "coreWeaponsData");
    if (!coreWeaponsData)
    {
   
        LogError(L, "Error getting coreWeaponsData ProcAddress from DLL");
        goto error;
    }

    coreMissionData = (f_coreMissionData)GetProcAddress(hGetProcIDDLL, "coreMissionData");
    if (!coreMissionData)
    {
   
        LogError(L, "Error getting coreMissionData ProcAddress from DLL");
        goto error;
    }

    coreDrawingsData = (f_coreDrawingsData)GetProcAddress(hGetProcIDDLL, "coreDrawingsData");
    if (!coreDrawingsData)
    {
   
        LogError

网站公告

今日签到

点亮在社区的每一天
去签到