Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Durere umar AC Joint

Care este cea mai sanatoasa paine?

Zgomot ritmic ce urmeaza rotirea ...

Merita Lumix FZ82 in 2024?
 Nu pot activa Memory Integrity

Supratensiuni accidentale

Cuțit/ briceag drumetie

Cum am acces la o parte dintr-un ...
 Mother's Day

Recomandare aparat de vidat alime...

Izolatie exterioara casa parter P...

Cuvinte si expresii neclare
 Mod de lucru Purmo Tempco Digital...

Samsung S90C vs LG C3

Problema sunet RCS

Amortizor sertare bucatarie
 

Apelat functie folosind un un cuvant ce contine instrucțiunile

- - - - -
  • Please log in to reply
5 replies to this topic

#1
lowly

lowly

    Junior Member

  • Grup: Members
  • Posts: 98
  • Înscris: 17.11.2012
Salut, am un server tcp, ce primeste un buffer de la client. Cum as putea executa acel buffer?
Exemplu:
Void func(int n)
{
Cout << "working"; }

int main()
{
Char buf[] = { "func(1)" };
}

Output dorit: " working "
Cum as putea apela ce este în buf?

#2
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Cam asa ai putea:

1. faci o structura de date in care specifici ce fel de parametri accepta fiecare functie si in ce ordine, si un pointer catre functia respectiva; numim aceasta structura "command registry"
2. parsezi buf, extragi din el primul cuvant; numim acest cuvant "function id"
3. te uiti in command registry la indexul lui "function id", si parsezi restul datelor din buf conform specificatiei din command registry
4. apelezi functia via function pointer din command registry

5. optional: scrii niste macros care sa iti usureze munca de construire a acelui command registry

#3
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Inca ceva, mi-am dat seama ca ai avea dificultati cu pasarea parametrilor care variaza, ai avea nevoie de ASM specific platformei, sistemului de operare, si calling convention.

Nu cred ca vrei sa te atingi de acele parti.

Mai bine:

modifica functia ca sa accepte un pointer la o lista generica (linked list), simplifica lucrurile enorm.


"Generica" in sensul C, cu o struct si cu un tip enum. Nu in sensul C++.

#4
lowly

lowly

    Junior Member

  • Grup: Members
  • Posts: 98
  • Înscris: 17.11.2012

View PostOriginalCopy, on 17 decembrie 2018 - 15:02, said:

Inca ceva, mi-am dat seama ca ai avea dificultati cu pasarea parametrilor care variaza, ai avea nevoie de ASM specific platformei, sistemului de operare, si calling convention.

Nu cred ca vrei sa te atingi de acele parti.

Mai bine:

modifica functia ca sa accepte un pointer la o lista generica (linked list), simplifica lucrurile enorm.


"Generica" in sensul C, cu o struct si cu un tip enum. Nu in sensul C++.
Ce as vrea eu sa fac implica clase, comenzile venite din client sunt pentru a adauga, modifica acele obiecte, salvarea fizica facandu-se de client (fie intr-un text, fie altceva, nu este implementata inca).
Metoda pe care o voi incerca, probabil, din punctul meu de vedere este simpla (*babeasca*):
- parsarea textului pana la '('
- identificarea functiei ce trebuie apelata, si tipul argumentului pe care functia il doreste
- stergem din buffer-ului initial numele functiei si parantezele, lasand doar argumentul
- apelarea functiei de catre server pe baza a ce a identificat, eventual conversii daca nu este de acelasi tip argumentul

Mersi de solutie Posted Image
Nu stiu in detaliu cum as putea face cu o lista
p.s. functiile au doar un argument

Edited by lowly, 17 December 2018 - 21:33.


#5
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,253
  • Înscris: 24.02.2007
Prea riscant cu function pointers

#include <iostream>
#include <functional>
#include <regex>
#include <string_view>
#include <unordered_map>

class CommandExecutor
{
public:
	void execute(const std::string& command)
	{
		std::cmatch match;
		if (std::regex_match(command.c_str(), match, command_expression_))
		{
			const std::string_view command_name(match[1].first, match[1].second - match[1].first);
			const std::string_view argument(match[2].first, match[2].second - match[2].first);

			const auto it = commands_.find(command_name);
			if (it != commands_.end())
			{
				it->second(argument);
			}
			else
			{
				//unknown command...

			}
		}
		else
		{
			//invalid command...
		}
	}

private:
	void foo(const std::string_view arg)
	{
		std::cout << "Executing foo(" << arg << ")\n";
	}

	void bar(const std::string_view arg)
	{
		std::cout << "Executing bar(" << arg << ")\n";
	}

#define REGISTER_COMMAND(name) \
	{#name, [this](const std::string_view arg) { this->name(arg); }}

	std::unordered_map<std::string_view, std::function<void(std::string_view)>> commands_ =
	{
		REGISTER_COMMAND(foo),
		REGISTER_COMMAND(bar)
	};
	std::regex command_expression_{ "^([a-zA-Z]+)\\((.*)\\)$" };
};

int main()
{
	CommandExecutor executor;
	executor.execute("foo(1234)");
	executor.execute("bar(hello_world)");
}



#6
lowly

lowly

    Junior Member

  • Grup: Members
  • Posts: 98
  • Înscris: 17.11.2012

View Postdani.user, on 18 decembrie 2018 - 00:22, said:

Prea riscant cu function pointers

#include <iostream>
#include <functional>
#include <regex>
#include <string_view>
#include <unordered_map>

class CommandExecutor
{
public:
void execute(const std::string& command)
{
std::cmatch match;
if (std::regex_match(command.c_str(), match, command_expression_))
{
const std::string_view command_name(match[1].first, match[1].second - match[1].first);
const std::string_view argument(match[2].first, match[2].second - match[2].first);

const auto it = commands_.find(command_name);
if (it != commands_.end())
{
it->second(argument);
}
else
{
//unknown command...

}
}
else
{
//invalid command...
}
}

private:
void foo(const std::string_view arg)
{
std::cout << "Executing foo(" << arg << ")\n";
}

void bar(const std::string_view arg)
{
std::cout << "Executing bar(" << arg << ")\n";
}

#define REGISTER_COMMAND(name) \
{#name, [this](const std::string_view arg) { this->name(arg); }}

std::unordered_map<std::string_view, std::function<void(std::string_view)>> commands_ =
{
REGISTER_COMMAND(foo),
REGISTER_COMMAND(bar)
};
std::regex command_expression_{ "^([a-zA-Z]+)\\((.*)\\)$" };
};

int main()
{
CommandExecutor executor;
executor.execute("foo(1234)");
executor.execute("bar(hello_world)");
}


Multumesc enorm de mult! A luat ceva pana am gasit cum sa instalez g++17 pe linux (versiunea buna, care poate rula string_view), l-am pus in codul meu si pot spune ca merge super. O sa il studiez mai in detaliu.

Anunturi

Neurochirurgie minim invazivă Neurochirurgie minim invazivă

"Primum non nocere" este ideea ce a deschis drumul medicinei spre minim invaziv.

Avansul tehnologic extraordinar din ultimele decenii a permis dezvoltarea tuturor domeniilor medicinei. Microscopul operator, neuronavigația, tehnicile anestezice avansate permit intervenții chirurgicale tot mai precise, tot mai sigure. Neurochirurgia minim invazivă, sau prin "gaura cheii", oferă pacienților posibilitatea de a se opera cu riscuri minime, fie ele neurologice, infecțioase, medicale sau estetice.

www.neurohope.ro

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate