Как вернуть указатель на структуру?
Возник вопрос как вернуть указатель на структуру. Знаю, что main ничего не возвращает,но как еще можно вернуть значения?
#define _GLIBCXX_USE_CXX11_ABI 0
#include <string>
#include <cstring>
#include "header.h"
#include <iostream>
#include <pqxx/pqxx>
using namespace std;
using namespace pqxx;
const char* sql = "";
struct SqlSelect{
int id;
char name;
}
void String_One( char* msg)
{
string s(msg);
sql = msg;
}
void connect() {
try {
connection C("dbname=user user=user password=user hostaddr=127.0.0.1");
if (C.is_open()) {
cout << "Opened database successfully: " << C.dbname() << endl;
} else {
cout << "Can't open database" << endl;
return 1;
}
SqlSelect select;
nontransaction N(C);
result R( N.exec( sql ));
for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
select->id = c[0].as<int>();
select->name = c[1].as<const char*>();
//как здесь вернуть указатель на структуру?
}
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return 1;
}
return 0;
}
Ответы (2 шт):
После завершения программы (main), впрочем, как и при выходе из любой функции, вся автоматическая память, то есть память, выделенная в стеке для локальных переменных функции, освобождается.
сам select не возвратится никак из программы. При возврате из функции в вызывающую функцию переменная select возвращается в виде копии (если не рассматривать механизм &&).
SqlSelect connect() { SqlSelect select; ... return select; }
Если это плагин к чему-то, то надо смотреть, какой интерфейс и как он организован между хостом и плагином. Если в виде dll - то можно вызвать как обычную функцию и return select.
Если это exe со своим main, то я не знаю, может можно выводить в выходной поток cout и на стороне хоста парсить эту строку.
Очень подробно всё написано в https://www.tutorialspoint.com/postgresql/postgresql_c_cpp.htm
Вы почему-то в функцию connect хотите дописать какой-то запрос. Имя функции должно быть таким, каким и действие. Напишите сначала функцию connect, потом select. Выводить результаты можно указателем на полученные значения. Выделяете память делаете задачу и возвращаете указатель.
Например, сначала подключаемся.
// возвращаем удачное подключение или nullptr
connection * connect ( void ) {
try {
connection * const C = new connection (
"dbname = testdb user = postgres password = cohondob "\
"hostaddr = 127.0.0.1 port = 5432");
if (C->is_open()) {
cout << "Opened database successfully: " << C->dbname() << endl;
} else {
delete C;
cout << "Can't open database" << endl;
return nullptr;
}
return C ;
} catch (const std::exception &e) {
cerr << e.what() << std::endl;
return nullptr;
}}
После удачного подключение вы сможете выполнять запросы. Аргументом будет служить удачное подключение и дополнительные аргументы для запроса. Результатом запроса будет служить массив структур. А какие структуры это уже в зависимости от запроса. Например запрос имени от идентификатора может возратить только одну запись или ничего. Тогда результатом функции будет указатель равный структуре или nullptr (если ответ был пустым).
struct SqlSelect {
int id ;
std :: string name;
} ;
SqlSelect * select_id_name(connection & C ) {
/* Create a non-transactional object. */
nontransaction N(C);
/* Execute SQL query */
result R( N.exec( "SELECT id , name FROM tablename WHERE id = 1 " ));
if(R.begin() == R.end())
// если запрос ничего не возратил
return nullptr ;
// если запрос прошёл, то выделяем память для структуры
// и записываем значения. Потом возвращаем её.
SqlSelect * select = new SqlSelect;
result::const_iterator c = R.begin();
select -> id = c[0].as<int>();
select -> name = c[1].as<std::string>();
return select ;
}