Передать getQuoteLevel2 в dll

Страницы: 1
RSS
Передать getQuoteLevel2 в dll
 
Спасибо этому форуму за советы и подсказки.
Как принять в dll таблицу с целочисленными ключами, разобрался.
Прошу подсказать как внутри dll разобрать по полям более сложную таблицу.
Код
qt=getQuoteLevel2(class, sec)
Согласно документации она возвращает таблицу, в которой два стринга и две вложенных таблицы.

Мне нужны для работы все четыре.
Как мне, к примеру, получить объём из 3-й котировки на покупку?

Для разбора таблицы с целочисленными индексами мой код внутри dll выглядит так:
Код
static int forLua_SumArray(lua_State* L) {
   // Get the length of the table (same as # operator in Lua)
   int n = lua_objlen(L, 1);
   double sum = 0.0;

   // For each index from 1 to n, get the table value as a number and add to sum
   for (int i = 1; i <= n; ++i) {
      lua_rawgeti(L, 1, i);
      sum += lua_tonumber(L, -1);
      lua_pop(L, 1);
   }

   lua_pushnumber(L, sum);
   return 1;
}
 
не проще взять готовый порт ? LuaInterface, luabind и т.п. ? ))
 
Может быть и проще, но я ничего про это не знаю.
Расскажите пожалуйста общий смысл.
 
Цитата
Let_it_go написал:
Может быть и проще, но я ничего про это не знаю.
Расскажите пожалуйста общий смысл.
Пишется класс в который оборачивается указатель на стейт.
Пишутся сервиные функции по типу чтения/записи с/на стек разного типа переменных. использование регистра. вызова функции. создания таблиц и т.д. вобщем обертка над lua c api. Дальше шаблонные функции исходя из того что им передают вызывают lua c api. для каждого параметра. В итоге код досточно простой получается.
Код
void OnMain(lua::qlua q)
{
    lua::table t = q.getQuoteLevel2("SPBFUT", "RIM8");
    int bid_count = t["bid_count"];    
    if (bid_count < 3) return;
    lua::table bid = t["bid"];
    if (bid == nil) return;
    lua::table bid3 = bid[3];
    const char* price = bid3["price"];     
    const char* quantity = bid3["quantity"]; 
}
extern "C" __declspec(dllexport) int luaopen_testlib(lua_State *L)
{    
    lua::qlua q(L);
    q["main"] = OnMain; //все что нужно для регистрации колбека (шаблон сам раскрывает параметры со стека исходя из сигнатуры функции и передает их в функцию выше. 
}
Готовые такие врапперы например
1) https://github.com/SteveKChiu/lua-intf
2) https://github.com/jeremyong/Selene
Как их подключать и использовать описано в каждом из проектов. В основном это просто заголовочные файлы. все достаточно просто, скачиваете, делаете include и готово)Мне вот например синтаксис использования этих врапперов не зашел. Пришлось изучить их вдоль и поперек и сам апи луа, в итоге свой враппер реализовал) но это долгий путь. лучше готовое взять. selene вполне неплох.
ps. еще на форум выкладывали враппер на макросах. где и функции+таблицы из qlua уже описаны были. тоже можно попробывать, как вариант.
 
Антон,
спасибо.
1. Проект создавать как и раньше в виде dll?
2. Код который вы написали, одинаковый для обоих врапперов?
 
и ещё вопрос. Я понял суть врапперов, естественно с ними проще.
но всё же, как решить мою задачу без них?
принять таблицу-стакан из OnQuote внутри dll? я сейчас читаю книгу по Луа, написанную её разработчиком. Иду шаг за шагом по главе "C API". В голове каша, но первые проблески уже есть. Строки и числа я уже спокойно обрабатываю в dll.
 
какой язык предпочтителен ?
C / C++ / C#
 
Цитата
Let_it_go написал:
но всё же, как решить мою задачу без них?
например так:
Код
void getQuote3(lua_State* L) {
    // t = getQuoteLevel2(c_code, s_code)
    lua_getglobal(L, "getQuoteLevel2"); //поместить на стек функцию 
    lua_pushstring(L, "SPBFUT"); //дальше идут параметры
    lua_pushstring(L, "RIM8"); 
    int num_args = 2, num_ret = 1;
    lua_pcall(L, num_args, num_ret, 0); //вызываем функцию, на стеке окажется таблица    
    
    lua_getfield(L, -1, "bid_count"); //из таблицы по индексу -1 взять значение ключа "bid_count" и поместить на стек
    int bid_count = lua_tointeger(L, -1);
    
    if (bid_count < 3) return;
    //на стеке -2 = t(table), -1 = bid_count(int)

    lua_getfield(L, -2, "bid"); //на стек положит таблицу со значениями стакана(bid)
    //на стеке -3 = t(table), -2 = bid_count(int), -1 = bid(table)
    lua_rawgeti(L, -1, 3); //из таблицы по индексу -1 взять значение ключа [3] и поместить на стек(еще 1 таблица=bid3)
    //на стеке -4 = t(table), -3 = bid_count(int), -2 = bid(table), -1 = bid3(table)

    //ну и из последней таблицы получаем необходимы значения
    lua_getfield(L, -1, "price");
    lua_getfield(L, -2, "quantity");
    const char * quantity = lua_tostring(L, -1);
    const char * price = lua_tostring(L, -2);
    //на стеке -6 = t(table), -5 = bid_count(int), -4 = bid(table), -3 = bid3(table), -2 = price(string), -1 = quantity(string)
    lua_pop(6); //чистим стек
}
 
Антон,
спасибо!!!
К тому моменту как увидел ваш ответ, уже накорябал свой вариант, но по прежнему не знал как читать вложенные таблицы (стакан и его поля).
Код
static int forLua_OnQuoteC(lua_State* L) {
   lua_pushnil(L);
   int s = 0;
   while (lua_next(L, -2))
   {
      s = s + 1;
      const char* key = lua_tostring(L, -2);
      double val = lua_tonumber(L, -1);
      lua_pop(L, 1);
   }
   return 1;
}
 
Антон, ура, скомпилировалось!
Я даже нашёл у вас опечатку
Код
lua_pop(L,6); //чистим стек (забыли букву L)
Но работать пока не работает.


Помогите пожалуйста написать финальные штуки (на них выскакивают ошибки) и.... вы сделали мой день :)
Код
static const struct luaL_Reg Stakan[] = {
{"getQuote3", getQuote3},
{NULL, NULL} /* sentinel */
};

extern "C" LUALIB_API int luaopen_Stakan(lua_State *L) {
   luaL_openlib(L, "Stakan", Stakan, 0);
   return 0;
}
Я не понимаю что писать в аргументы внутри круглых и фигурных скобок.
Компилятор пишет:



Шапка вверху у меня такая:
Код
#include "stdafx.h"
#define LUA_LIB
#define LUA_BUILD_AS_DLL
extern "C" {
#include "lauxlib.h"
#include "lua.h"
#include "lauxlib.h"
}
// стандартная точка входа для DLL
BOOL APIENTRY DllMain(HANDLE hModule,
   DWORD  ul_reason_for_call,
   LPVOID lpReserved
)
{
   return TRUE;
}
 
Если вы пытаетесь скомпилировать функцию предложенную Антоном как есть то там ошибка в объявлении функции.
Вместо
void getQuote3(lua_State* L) {
....

Надо писать

static int getQuote3(lua_State* L) {
....
return 0
}

это обязательный формат для всех регестрируемых в луа С функций
 
Просто думал вызов будет каким-то таким, не ошибка)
Код
static int forLua_SumArray(lua_State* L) {
    getQuote3(L);
    /* остальное */ 
}
Но вообще да. я код не компилил и не проверял на 100% правильность так что возможно гдето еще недочеты.
Если нужно этот код из lua вызывать то да, все функции которые пробрасываем в луа
Код
lua_CFunction=int(lua_State*)
что компилятор вам и указал во 2й строке скриншота
 
Код компилируется без ошибок, формируется dll-файл, но в error list остались ошибки.


Последние две указывают на строчку 49:



Полный текст кода сейчас такой:
Код
#include "stdafx.h"
#define LUA_LIB
#define LUA_BUILD_AS_DLL
extern "C" {
#include "lauxlib.h"
#include "lua.h"
#include "lauxlib.h"
}
// стандартная точка входа для DLL
BOOL APIENTRY DllMain(HANDLE hModule,
   DWORD  ul_reason_for_call,
   LPVOID lpReserved
)
{
   return TRUE;
}
static int getQuote3(lua_State* L) {
   // t = getQuoteLevel2(c_code, s_code)
   lua_getglobal(L, "getQuoteLevel2"); //поместить на стек функцию 
   lua_pushstring(L, "SPBFUT"); //дальше идут параметры
   lua_pushstring(L, "RIU8");
   int num_args = 2, num_ret = 1;
   lua_pcall(L, num_args, num_ret, 0); //вызываем функцию, на стеке окажется таблица   
   lua_getfield(L, -1, "bid_count"); //из таблицы по индексу -1 взять значение ключа "bid_count" и поместить на стек
   int bid_count = lua_tointeger(L, -1);
   if (bid_count < 3) {
      return 0;
   }
   //на стеке -2 = t(table), -1 = bid_count(int)
   lua_getfield(L, -2, "bid"); //на стек положит таблицу со значениями стакана(bid)
   //на стеке -3 = t(table), -2 = bid_count(int), -1 = bid(table)
   lua_rawgeti(L, -1, 3); //из таблицы по индексу -1 взять значение ключа [3] и поместить на стек(еще 1 таблица=bid3)
   //на стеке -4 = t(table), -3 = bid_count(int), -2 = bid(table), -1 = bid3(table)
   //ну и из последней таблицы получаем необходимы значения
   lua_getfield(L, -1, "price");
   lua_getfield(L, -2, "quantity");
   const char * quantity = lua_tostring(L, -1);
   const char * price = lua_tostring(L, -2);
   //на стеке -6 = t(table), -5 = bid_count(int), -4 = bid(table), -3 = bid3(table), -2 = price(string), -1 = quantity(string)
   lua_pop(L, 6); //чистим стек
   return 0;
}

static const struct luaL_Reg mylib[] = {
{"l_getQuote3", getQuote3},
{NULL, NULL} /* sentinel */
};

extern "C" LUALIB_API int luaopen_Stakan(lua_State *L) {
   luaL_openlib(L, "Stakan", mylib, 0);
   return 0;
}
 
всё зависит от проекта. Какая версия компоновщика. версия IDE
что у вас в #include "stdafx.h"
 
Павел Валин, да там все верно. ошибки такие с которыми dll точно бы не сбилдилась. старые мб остались. не видит функции с которыми длл билдится. ерунда вобщем

проверил на vs2017 все ок. ошибок с кодом выше 0.
 
Антон, угу. я даж с поддеркой CLR это запустить смог.
короч странно да. Пару раз мне такую же шляпу написало. но слинковал и всё запустилось.
кэш зло )
Страницы: 1
Читают тему
Наверх