Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Mi-au disparut amigdalitele ?

Exista vreun plan de terorizare p...

Schimbare adresa DNS IPv4 pe rout...

Recomandare Barebone
 Monede JO 2024

Suprasolicitare sistem electric

CIV auto import

Mutare in MOZAMBIC - pareri, expe...
 Scoatere antifurt airtag de pe ha...

Magnet in loc de clește pent...

Cumparat/Locuit in apartament si ...

Pot folosi sistemul PC pe post de...
 Sokol cu distorsiuni de cross-over

Filtru apa potabila cu osmoza inv...

Kanal D va difuza serialul “...

Upgrade xiaomi mi11
 

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,236
  • Î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

Chirurgia endoscopică a hipofizei Chirurgia endoscopică a hipofizei

"Standardul de aur" în chirurgia hipofizară îl reprezintă endoscopia transnazală transsfenoidală.

Echipa NeuroHope este antrenată în unul din cele mai mari centre de chirurgie a hipofizei din Europa, Spitalul Foch din Paris, centrul în care a fost introdus pentru prima dată endoscopul în chirurgia transnazală a hipofizei, de către neurochirurgul francez Guiot. Pe lângă tumorile cu origine hipofizară, prin tehnicile endoscopice transnazale pot fi abordate numeroase alte patologii neurochirurgicale.

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