Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: rcbandit в Apr 06, 2011, 22:54



Титла: Как да извикам функция?
Публикувано от: rcbandit в Apr 06, 2011, 22:54
Имам следния проблем

Имам този JSON стринг

Код
GeSHi (Javascript):
  1. {
  2.     "program": {
  3. "destination": "400",
  4. "function": {
  5.     "value1": "123",
  6.     "value2": "123"
  7. }
  8.     }
  9. }
  10.  

Трябва от този код като се получи да се извика функция и да й се предадът двете променливи
Успях да подкарам обръщането на абикновенни променливи в JSON стринг и обратно, но сега как да се извика функцията следкато се получи и се обърне пак в стойности

Код
GeSHi (C):
  1. #include <jansson.h>
  2. #include <string.h>
  3. #include "util.h"
  4.  
  5. int main()
  6. {
  7.  
  8. /*
  9. {
  10.     "program": {
  11. "destination": "400",
  12. "function": {
  13.     "value1": "123",
  14.     "value2": "123"
  15. }
  16.     }
  17. }
  18.  
  19. */
  20.  
  21. /*generate this string*/
  22.  
  23.     char *resultz;
  24.  
  25. json_t *root, *rootz, *computer_listing;
  26.  
  27. computer_listing = json_object();
  28.   json_object_set_new(computer_listing, "varible1", json_string("STX"));
  29.   json_object_set_new(computer_listing, "varible2", json_string("STlX"));
  30.  
  31.   root = json_object();
  32. json_object_set_new(root, "destination", json_string("400"));
  33.   json_object_set_new(root, "Function", computer_listing);
  34.  
  35.  
  36. rootz = json_object();
  37.   json_object_set_new(rootz, "DX57", root);
  38.  
  39. resultz = json_dumps(rootz, 0);
  40.  
  41. printf("%s", resultz);
  42.  
  43.  
  44.  
  45. /* The idea is that this message came from somewhere else */
  46. const char *msg =
  47. "{\"program\": {\n"
  48. "    \"destination\": 400,\n"
  49. "    \"function\": {\n"
  50. "      \"value1\": 123,\n"
  51. "      \"value2\": 123\n"
  52. "    }\n"
  53. "  }\n"
  54. "}\n";
  55.  
  56. int destination, value1, value2, result;
  57. json_t *msg_j;
  58. json_error_t err;
  59.  
  60. msg_j = json_loads(msg, 0, &err);
  61. if (!msg_j) {
  62. fprintf(stderr, "%s\n", err.text);
  63. return 1;
  64. }
  65.  
  66. result = json_unpack_ex(msg_j, &err, JSON_STRICT, "{s:{s:i, s:{s:i, s:i}}}"
  67. , "program", "destination", &destination
  68. , "function", "value1", &value1, "value2", &value2);
  69. json_decref(msg_j);
  70.  
  71. if (result) {
  72. fprintf(stderr, "%s\n", err.text);
  73. return 1;
  74. }
  75.  
  76. printf("Success!\ndestination: %i, value1: %i, value2: %i\n", destination, value1, value2);
  77. return 0;
  78.  
  79.  
  80.  
  81.  
  82.    return 0;
  83. }
  84.  

Горното го написах използвайки библиотеката JANSSON


Титла: Re: Как да извикам функция?
Публикувано от: b2l в Apr 06, 2011, 23:01
Нищо не мога да разбера от въпроса ти.


Титла: Re: Как да извикам функция?
Публикувано от: clovenhoof в Apr 06, 2011, 23:42
// off
Четейки въпроса се сетих за това : http://www.youtube.com/watch?v=Du5eFmessRA ($2)


Титла: Re: Как да извикам функция?
Публикувано от: b2l в Apr 06, 2011, 23:46
// off
Четейки въпроса се сетих за това : http://www.youtube.com/watch?v=Du5eFmessRA ($2)

Хахахахаха - ти ме уби направо бе :D :D :D :D :D  [_]3 [_]3 [_]3 [_]3 [_]3 [_]3 [_]3


Титла: Re: Как да извикам функция?
Публикувано от: rcbandit в Apr 07, 2011, 00:09
Пример: Да кажем че имаме 6 функции в един демон. Демона получава този JSON. Целта изпращането на JSON стринга е да му се каже на демона какво да прави - коя функция дя извика и какви параметри да подаде. Получава нещо като набор от каманди за изпълнение от демона. Как ще стане това в случая.


Титла: Re: Как да извикам функция?
Публикувано от: gat3way в Apr 07, 2011, 00:32
http://www.newty.de/fpt/index.html


Титла: Re: Как да извикам функция?
Публикувано от: rcbandit в Apr 07, 2011, 01:17
Код
GeSHi (C):
  1. int main()
  2. {
  3.    int select, count;
  4.  
  5.    select = 1;
  6.    switch( select )
  7.    {
  8.        case 1: insert( count, lift );
  9.                break;
  10.  
  11.        case 2: update( count, step );
  12.                break;
  13.  
  14.        case 3: remove( count, drop );
  15.                /* Fall through to next case */
  16.        default:
  17.                break;
  18.    }
  19. }

Има ли по-оптимизирано решение на горния код. Проблема е че яко имам много функции switch case става прекалено толям.


Титла: Re: Как да извикам функция?
Публикувано от: gat3way в Apr 07, 2011, 01:36
Цялата идея на това беше да се избегнaт switch-овете, ползвайки указатели към функции. Разбери, че няма да станат тези неща с копи-пействане, това не е модване на някакъв PHP-базиран CMS. Трябва поне малко да осмислиш за какво става въпрос.


Титла: Re: Как да извикам функция?
Публикувано от: rcbandit в Apr 07, 2011, 02:09
Код
GeSHi (C):
  1. void Replace_A_Switch()
  2. {
  3.  
  4.   Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
  5. }
  6.  
  7.  
  8. void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
  9. {
  10.   float result = pt2Func(a, b);  
  11.  
  12. }
  13.  

най-накрая схванах!
добре a какво се прави в случай когато веднъж имаме 3 аргумента а друг път повече? Има ли някакво решение?
Просто правя функцията сповече аргументи и предавам NULL на излишните аргументи?


Титла: Re: Как да извикам функция?
Публикувано от: d0ni в Apr 07, 2011, 02:35
в твоя случай най-добре е да предаваш json обекта като един параметър и всяка функция да си го обикаля и да си чете каквото й е нужно.

също така може да избегнеш switch/if, ако функциите ти ги сложиш в отделен .so файл и ги извикваш с dlopen/dlsym от демона


Титла: Re: Как да извикам функция?
Публикувано от: rcbandit в Apr 17, 2011, 11:23
Отново имам проблеми с викането на функцията:
Извикването не се получава

Код:
#include"hashtbl.h"
#include <stdio.h>
#include <string.h>

void (*Load_Function_Pointer)(int z) = NULL;

void gor(int z) { printf("gor\n"); }


int main()
{


HASHTBL *hashtbl;

if(!(hashtbl=hashtbl_create(16, NULL))) {
fprintf(stderr, "ERROR: hashtbl_create() failed\n");
exit(EXIT_FAILURE);
}

hashtbl_insert(hashtbl, "zzs", "gor");
hashtbl_insert(hashtbl, "ssd", "top");

char *Mob = "zzs";

Load_Function_Pointer = hashtbl_get(hashtbl, Mob);
void (*Load_Function_Pointer)(int z);

hashtbl_destroy(hashtbl);

return 0;
}

Търсенето на на стойност по ключ се получава но когато трябва да се предаде имено на функцията към pointer не се получава.

Някакви идей как да се реши проблема?


Прикрепям пълния код

п.п и с горния начин на викане на функция не става - връща грешка Segmentation fault при викане


Титла: Re: Как да извикам функция?
Публикувано от: bvbfan в Apr 17, 2011, 12:33
Код
GeSHi (C):
  1. /* in hashtbl.h */
  2. typedef void* data_t;
  3.  
  4. /* in main.cpp */
  5. typedef void (*user_func)(int);
  6. void test( int i ) { printf( "Called test with argument = %d\n", i ); }
  7.  
  8. int main()
  9. {
  10. HASHTBL *hashtbl;
  11. user_func user;
  12. const char *func_key = "test function";
  13.  
  14. if(!(hashtbl=hashtbl_create(16, NULL))) {
  15. fprintf(stderr, "ERROR: hashtbl_create() failed\n");
  16. exit(EXIT_FAILURE);
  17. }
  18.  
  19. hashtbl_insert(hashtbl, func_key, (data_t)test);
  20.  
  21. user = (user_func)hashtbl_get(hashtbl, func_key);
  22.  
  23. user( 5 );
  24.  
  25. hashtbl_destroy(hashtbl);
  26.  
  27. return 0;
  28. }
  29.  

PS: Ако има някакви проблеми, мога да помогна, но нямам много свободно време  ;)


Титла: Re: Как да извикам функция?
Публикувано от: rcbandit в Apr 17, 2011, 12:49
много благодаря, това е предостатъчно

п.п кой варянт ви се вижда по добър:

1. Да сложа всички функции в един демон и за ги викам използвайки hash table и function pointer

2. Да сложа всяка функция в отделен .so файл и да ги зареждам по време на зареждане използвайки Dynamic loading and un-loading of shared libraries using libdl като предполагам се избягва hash table.

Кой би бил по-бърз и удобен?