ArisHu
ArisHu

Reputation: 48

How to call managed c++ dll functions in lua cpp module

Description:

All my functions are defined in C# dll project.Then I wrap the c# functions in a cpp library project,Now I want to write a lua module using c++ and call the wrapper function.

Question:

How to call the wrapper functions in lua cpp module? Please give me some suggestions, Thanks!

Codes:

  1. libutilscore Project(C# DLL)

     namespace libutilscore
     {
         public static class SharpFTP
         {
             public static string ShowHello()
             {
                 return "Hello From C Sharp.";
             }
         }
      }
    
  2. ManagedDll Project(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 Project(Lua CPP Module)
    • 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 Call DLL function
          // 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;
      }
      

Upvotes: 1

Views: 363

Answers (1)

Kevin Anderson
Kevin Anderson

Reputation: 7010

One option MAY be to make your "Lua CPP Module" a mixed-mode DLL. I have answered previously on this topic, so read my instructions there on how to do it: VC++ Calling a function of /clr project from a function of non /clr project within a solution The short answer is that you can compile specific parts of a DLL to use the CLR without making the whole thing that way, and then call between them.

Basically, once you've figured out how to call a mixed-mode DLL from PURE C++ code, then this problem is very similar. I don't know about restrictions on LUA C++ modules, though I would presume if they can load/call other DLLs, then you're fine.

For extra fun, then figure out how to pass information all the way back and forth. And calling pure C++ from C#/.NET. Or callbacks to/from each. That gets really fun quickly.

Upvotes: 1

Related Questions