كيف يمكنني استدعاء وظائف C++ من برنامج Lua النصي؟

StackOverflow https://stackoverflow.com/questions/1209748

  •  06-07-2019
  •  | 
  •  

سؤال

أنا أستخدم Visual Studio 2005.

------------------------[ luapassing.cpp ]--------------------

#include "lua.h"
static int myCfunc (Lua_State *L){
   double trouble = lua_tonumber(L,1);
   lua_pushnumber(L,16.0 -trouble);
   return 1;
}
int luaopen_luapassing (Lua_State *L){
   static const lua_reg Map [] = {{"dothis",myCfunc},{NULL,NULL}};
   luaL_register(L,"cstuff",Map);
   return;
}

-------------------------[ csample.lua]-------------------- -----

package.cpath = "./CLua2.dll"
require "luapassing"

print("hola")
print(seth.doThis(120))
هل كانت مفيدة؟

المحلول

أرى عدة قضايا.سأصفها، وأقدم جزءًا من التعليمات البرمجية التي يجب أن تعمل كما أعتقد أنك قصدت أن تعمل هذه العينة.

مشكلتك الأولى هي أن مترجم C++ شوه اسم الوظيفة الوحيدة المصدرة من ملف DLL الخاص بك والذي يهم اسمه Lua: luaopen_luapassing().تم تجميع التوزيع الثنائي للمخزون لنظام التشغيل Windows كبرنامج C، ويفترض اسم نمط C لنقطة إدخال وحدة DLL.

أيضا، لديك بروتوكول ل luaopen_x وظيفة خاطئة قليلا.تقوم الدالة بإرجاع عدد صحيح يخبر Lua بعدد العناصر الموجودة أعلى مكدس Lua والتي تمثل قيمًا مرجعية للاستخدام بواسطة Lua.البروتوكول الذي يفترضه require تفضل أن تترك كائن جدول الوحدة الجديدة في الجزء العلوي من المكدس وتعيده إلى Lua.للقيام بذلك، luaopen_x سوف تستخدم الوظيفة عادة luaL_register() كما فعلت، ثم العودة 1.

هناك أيضا مسألة التسمية.الوحدات المكتوبة بلغة Lua النقية لديها الفرصة لتكون أقل وعيًا بأسمائها.لكن الوحدات المكتوبة بلغة C يجب أن تقوم بتصدير دالة من مكتبة الارتباط الحيوي (DLL) تتضمن اسم الوحدة في اسمها.يجب عليهم أيضًا تقديم اسم الوحدة هذا إلى luaL_register() بحيث يتم إنشاء الجدول الصحيح وتحديثه في البيئة العالمية.أخيرًا، سيرى البرنامج النصي للعميل Lua الوحدة المحملة في جدول عام مسمى مثل الاسم الذي تم تمريره إليه require, ، والذي تم إرجاعه أيضًا من require بحيث يمكن تخزينه مؤقتًا محليًا في هذا البرنامج النصي.

هناك بعض الصئبان الأخرى التي تحتوي على رمز C وهي أنه يجب كتابة النوع الرقمي بالفعل lua_Number لسهولة النقل، وأنه سيكون تقليديا للاستخدام luaL_checknumber() بدلا من lua_tonumber() لفرض الوسيطة المطلوبة للوظيفة.أنا شخصياً سأسمي تطبيق C للوظيفة العامة باسم مرتبط باسمها والذي سيعرفه Lua علنًا، لكن هذه مجرد مسألة ذوق.

يجب أن يعمل هذا الإصدار من الجانب C على إصلاح هذه المشكلات:

#include "lua.h"
static int my_dothis (Lua_State *L){
   lua_Number trouble = luaL_checknumber(L,1);
   lua_pushnumber(L,16.0 -trouble);
   return 1;
}
extern "C" int luaopen_luapassing (Lua_State *L){
    static const lua_reg Map [] = {
        {"dothis", my_dothis},
        {NULL,NULL}
    };
    luaL_register(L,"luapassing",Map);
    return 1;
}

يحتاج نموذج البرنامج النصي بعد ذلك إلى الإشارة إلى الوحدة المحملة باسمها الصحيح، وإلى الوظائف المحددة بواسطة تلك الوحدة بأسمائها الصحيحة.Lua حساسة لحالة الأحرف، لذلك إذا قامت الوحدة بإنشاء وظيفة تسمى dothis(), ، فيجب أن يستخدم البرنامج النصي نفس الاسم، ولا يمكن العثور عليه بالاسم doThis(), ، على سبيل المثال.

require "luapassing"

print("hola")
print(luapassing.dothis(120))

يجب أن أضيف أنني لم أقم بالفعل بتجميع ما ورد أعلاه وتشغيله، لذلك قد يكون هناك خطأ مطبعي أو خطأين متبقيين كتمرين؛-)

نصائح أخرى

إذا كنت تنوي أن تفعل الكثير من C ++ للوا ملزمة، قد ترغب في إلقاء نظرة على الموقع luabind .

إذا كنت تجميع كما C ++ وتريد أن تطابق واجهة "C"، يجب أن يعلن وظائف مرئية من الخارج كما extern "C" لتجنب اسم تغيير اسم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top