如何在lua cpp模块中调用托管c++ dll函数

说明

所有的函数都在C#dll项目中定义,然后我将c#函数封装到cpp库项目中,现在我想编写一个使用c++编写的lua模块,并调用封装函数。

问题:

如何在lua cpp模块中调用包装器函数?请给我一些建议,谢谢!

代码:

  1. libutilscore项目(C#DLL)

     namespace libutilscore
     {
         public static class SharpFTP
         {
             public static string ShowHello()
             {
                 return "Hello From C Sharp.";
             }
         }
      }
    
  2. ManagedDll项目(C++ DLL)

    • ManagedDll.h

      #pragma once
      #ifdef MANAGEDDLL_EXPORTS
      #define MANAGEDDLL_API __declspec(dllexport)
      #else
      #define MANAGEDDLL_API __declspec(dllimport)
      #endif
      
      MANAGEDDLL_API const char *CPP_ShowHello();
      
    • ManagedDll.cpp

      #include "ManagedDll.h"
      #include <string>
      using namespace System;
      using namespace std;
      using namespace libutilscore;
      
      namespace ManagedDll
      {
         public ref class CS_FTP
         {
             public:
                static string CS_ShowHello()
                {
                    String ^ message = libutilscore::SharpFTP::ShowHello();
                    string result = "";
                    MarshallString(message, result);
                    return result;
                }
             private:
                static void MarshallString(String ^csstr, string &stdstr)
                {
                    using namespace Runtime::InteropServices;
                    const char *chars = (const char*)(Marshal::StringToHGlobalAnsi(csstr)).ToPointer();
                    stdstr = chars;
                    Marshal::FreeHGlobal(IntPtr((void *)chars));
                }
      
                static void MarshallWstring(String ^csstr, string &wstr)
                {
                    using namespace Runtime::InteropServices;
                    const char *wchars = (const wchar_t*)(Marshal::StringToHGlobalAnsi(csstr)).ToPointer();
                    wstr = wchars;
                    Marshal::FreeHGlobal(IntPtr((void *)wchars));
                }
          };
      }
      
      MANAGEDDLL_API string CPP_ShowHello()
      {
          return ManagedDll::CS_FTP::CS_ShowHello();
      }
      
      1. libutils项目(LuaCPP模块)
    • libutils.h

      #pragma once
      
      #ifdef LIBUTILS_EXPORTS
          #define LIBUTILS_API __declspec(dllexport)
      #else
          #define LIBUTILD_API __declspec(dllimport)
      #endif // LIBUTILS_EXPORTS
      
    • libutils.cpp

      #include "libutils.h"
      #include "lua.hpp"
      
      LIBUTILS_API int showHello(lua_State *luaEnv)
      {
          const char *msg = "";
          // TODO 调用DLL函数
          // msg = CPP_ShowHello().c_str();
          lua_pushstring(luaEnv, msg);
          return 1;
      }
      
      static const luaL_Reg libutils_funcs[] = {
          {"showHello", showHello},
          {"NULL", NULL}
      };
      
      LIBUTILS_API int luaopen_libutils(lua_State *luaEnv)
      {
          luaL_newlib(luaEnv, libutils_funcs);
          return 1;
      }
      
点赞
用户83839
用户83839

一种方法可能会是让你的“Lua CPP Module”成为一个混合模式 DLL。我之前已经回答过这个问题,所以请阅读我的指令:VC++ Calling a function of/clr project from a function of non/clr project within a solution。简单来说,你可以仅将 DLL 的特定部分编译成 CLR 以供使用,而不是整个项目,然后在它们之间进行调用。

基本上,一旦你已经搞清楚如何从纯 C++ 代码调用混合模式 DLL,那么这个问题就非常相似。我不知道 LUA C++ 模块是否有限制,但我会认为如果它们可以加载/调用其他 DLL,则你会很好。

对于额外的乐趣,你可以尝试想办法将信息来回传递,或是从 C#/.NET 调用纯 C++,或是进行回调。这会非常快乐。

2018-05-11 14:25:47