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



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)
    {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PH_modest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值