Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.222.182.105] |
|
Страницы: (8) [1] 2 3 ... 7 8 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Уважаемые знатоки С++, подскажите решение такого вопроса:
имеется .DLL .Lib и .H требуется написать класс на чистом С++ для использования функций из этой DLL-ки (dll-ка на Си) Если работа ведется в MSVS2015C++ Как я предполагаю нужно сделать "Пустой проект" или же можно "Консольное приложение Win32" я выбрал "Пустой проект" , добавляю к проекту lib и h , dll-ку ложу к exe-шнику , добавляю main.cpp, делаю Добавить Класс С++, при создании нужно ли ставить "Виртуальный деструктор" вот HyTech.h #pragma once #include "HSCLI.H" #include <stdio.h> #define SIZE_HCSQLDSTINFOT 128 class HyTech { public: int err = 0 ; // Код ошибки int pdb = 0 ; // Адрес памяти, куда будет записан идентификатор соединения. int pOper = 0 ; // Адрес памяти, куда будет записан идентификатор оператора. int pCol = 0 ; // кол-во колонок long pStr = 0 ; // кол-во строк unsigned pRecSize = 0 ; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOp = 0 ; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". HyTech(); ~HyTech(); int ConnectServer(int pdb, char* pStrConnect, char * pStrLogin, char * pStrPassword);//char *pStrConnect, char *pStrLogin, char *pStrPassword int SqlQuery(int pdb, char *pStrSql); int PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, char** dataRes); int CloseSqlQuery(int pOper); int CloseConnectServer(int pdb); }; вот HyTech.cpp #define HYCFG_WIN32 #include "HyTech.h" HyTech::HyTech() { } int HyTech::ConnectServer(int pdb, char* pStrConnect, char * pStrLogin, char* pStrPassword) { int hdb; // Адрес памяти, куда будет записан идентификатор соединения. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации if (err = hcSqlInit(&Init) != 0) return err; // Инициализация клиентской части if (err = hcSqlCheckInit() < 0) return err; // Проверка завершения инициализации if (err = hcSqlAllocConnect(&hdb) != 0) return err; // Создать соединение pdb = hdb; if (err = hcSqlConnect(pdb, pStrConnect, pStrLogin, pStrPassword) != 0) return err; //Установить связь с СУБД return err; } int HyTech::SqlQuery(int pdb, char *pStrSql) { int pOperTemp; unsigned int cntOpTemp; if (err = hcSqlAllocStmt(pdb, &pOperTemp) != 0) return err; // Создать оператор pOper = pOperTemp; if (err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) != 0) return err; // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях if (err = hcSqlExecDirect(pOper, pStrSql) != 0) return err; // Выполняем SQLзапрос if (err = hcSqlNumResultCols(pOper, &pCol) != 0) return err; // Получить количество колонок результата if (err = hcSqlRowCount(pOper, &pStr) != 0) return err; // Получить количество строк результата if (err = hcSqlOpenResults(pOper, &pRecSize) != 0) return err; // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOpTemp) != 0) return err;// Получить информацию об операторе cntOp = cntOpTemp; return pOper; } int HyTech::PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, char** dataRes) { static const size_t _n50 = 50; dataRes = new char*[_n50]; for (int i = 0; i < pCol; ++i) dataRes[i] = new char[_n50]; char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, position, bufOut , pRecSize * _n50, &cntOut);// Чтение результатов char *p = bufOut ; // делаем указатель на буфер int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 1; ib <= nomRecBuf; ib++) // перебираем строки записанные в буфер { for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //dataRes[ib][j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ) ;// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dataRes[ib][j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dataRes[ib][j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } } for (int i = 0; i < pCol; ++i) delete[] dataRes[i]; delete[] dataRes; return 0; } int HyTech::CloseSqlQuery(int pOper) { hcSqlCloseResults(pOper); // Закрытие доступа к результатам return 0; } int HyTech::CloseConnectServer(int pdb) { hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы return 0; } Добавлено У меня следующие вопросы : 1) правильно ли я делаю ? 2) архитектура класса , правильно не правильно , как лучше, что сделать переделать как лучше организовать 3) сам код, как правильней и красивей |
Сообщ.
#2
,
|
|
|
А где удаление самого́ bufOut'а в HyTech::PasStr опосля? (ну и похожий вопрос про infCol в HyTech::SqlQuery).
|
Сообщ.
#3
,
|
|
|
Цитата Славян @ А где удаление самого́ bufOut'а в HyTech::PasStr опосля? (ну и похожий вопрос про infCol в HyTech::SqlQuery). ОК , понял , сейчас смотрю Добавлено файл main.cpp #define HYCFG_WIN32 #include "HyTech.h" //using namespace std; int main(int argc, char* argv[]) { HyTech hT1; int pdb = 0 ; char server[25]; char login[25]; char password[25]; std::cin >> server; std::cin >> login; std::cin >> password; hT1.ConnectServer( pdb, server, login, password); return 0; } выполняю , получаю две ошибки ОшибкаLNK1120неразрешенных внешних элементов: 1ComPro1C:\Users\Admin\Desktop\ComPro1\Debug\ComPro1.exe1 ОшибкаLNK2019ссылка на неразрешенный внешний символ "public: __thiscall HyTech::~HyTech(void)" (??1HyTech@@QAE@XZ) в функции _mainComPro1 \ComPro1\main.obj1 Добавлено ~HyTech(); переставил на последнее место и стало нормально Добавлено Цитата Славян @ А где удаление самого́ bufOut'а в HyTech::PasStr опосля? (ну и похожий вопрос про infCol в HyTech::SqlQuery). а ~HyTech() разве не удаляет все объекты класса, |
Сообщ.
#4
,
|
|
|
Цитата kms @ У меня следующие вопросы : 1) правильно ли я делаю ? 2) архитектура класса , правильно не правильно , как лучше, что сделать переделать как лучше организовать 3) сам код, как правильней и красивей на самом деле в инете много примеров оберток под разные СУБД например я юзал обертку для SQLite3 C API, готовую естесно сам я неумею их писать можешь зайти по ссылке https://github.com/Cfon/MFCSQLite3Demo скачать мой пример там есть сорсы этой обертки пс. обертка там простая, тебе надо тока знать сам HyTECH C API, чтобы адаптировать под себя |
Сообщ.
#5
,
|
|
|
Цитата Cfon @ скачать мой пример там есть сорсы этой обертки ОК , сейчас смотрю тут еще такой вопрос , я как то не правельно передаю int pdb в err = hT1.ConnectServer( pdb, server, login, password); после как функция отработала pdb = 0 т.е. не получает адрес, хотя отладчиком иду по функции , pdb адрес получает |
Сообщ.
#6
,
|
|
|
Цитата kms @ Ну у вас bufOut и infCol некие левые локальные переменные, так что деструктор не должен удалять их. а ~HyTech() разве не удаляет все объекты класса |
Сообщ.
#7
,
|
|
|
Цитата Славян @ Ну у вас bufOut и infCol некие левые локальные переменные, так что деструктор не должен удалять их. подскажите как мне правильно разрулить с пременными и деструктором Добавлено ~HyTech() опять дал ошибку пришлось закоментировать опять Добавлено Cfon если я правильно понял посмотрев исходники по твоей ссылке получается что переменные надо прятать в private: |
Сообщ.
#8
,
|
|
|
Цитата kms @ ~HyTech() опять дал ошибку пришлось закоментировать опять так вы нигде не реализовали эту функцию, вот и ругается |
Сообщ.
#9
,
|
|
|
Цитата Алексей_Л @ так вы нигде не реализовали эту функцию, вот и ругается вот блин точно, щас |
Сообщ.
#10
,
|
|
|
Цитата kms @ Да я про простые замечания вроде такого:подскажите как мне правильно разрулить с пременными и деструктором class HyTech { hcSqlDstInfoT *infCol; // своя public: HyTech() { infCol = NULL; } ~HyTech() { if( infCol ) delete [] infCol; } ... } int HyTech::SqlQuery(int pdb, char *pStrSql) { ... infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" if(err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOpTemp) != 0) return err;// Получить информацию об операторе ... } int HyTech::PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, char** dataRes) { static const size_t _n50 = 50; dataRes = new char*[_n50]; for (int i = 0; i < pCol; ++i) dataRes[i] = new char[_n50]; char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. ... delete[] dataRes; delete [] bufOut; // освобождаем память return 0; } |
Сообщ.
#11
,
|
|
|
Цитата Славян @ Да я про простые замечания вроде такого: ОК, исправляю Добавлено Цитата Славян @ Только вот при вызове PasStr надо бы не запутаться где своя infCol, а где чужая. понял буду смотреть |
Сообщ.
#12
,
|
|
|
вот что у меня получается на данный момент
файл HyTech.h Скрытый текст #ifndef _HYTECH_H_ #define _HYTECH_H_ #include "HSCLI.H" #include <iostream> #define SIZE_HCSQLDSTINFOT 128 class HyTech { hcSqlDstInfoT *infCol; // Структура "Информация о колонках результата" public: HyTech(); ~HyTech(); int ConnectServer( char* pStrConnect, char * pStrLogin, char * pStrPassword ); // Подключение к серверу int SqlQuery( char *pStrSql ); // Выполняем запрос int PasStr( ); // Чтение результата int CloseSqlQuery(); // Закрываем запрос int CloseConnectServer(); // Отключаемся от сервера private: int pdb = 0 ; // Адрес памяти, куда будет записан идентификатор соединения. int pOper = 0 ; // Адрес памяти, куда будет записан идентификатор оператора. int pCol = 0 ; // кол-во колонок long pStr = 0 ; // кол-во строк unsigned pRecSize = 0 ; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOp = 0 ; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". }; #endif файл HyTech.cpp Скрытый текст #define HYCFG_WIN32 #include "HyTech.h" HyTech::HyTech() { infCol = NULL; } HyTech::~HyTech() { if (infCol) delete[] infCol; } int HyTech::ConnectServer( char* pStrConnect, char * pStrLogin, char* pStrPassword )/*Подключение к серверу*/ { int err; int hdb; // Адрес памяти, куда будет записан идентификатор соединения. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации if (err = hcSqlInit(&Init) != 0) return err; // Инициализация клиентской части if (err = hcSqlCheckInit() < 0) return err; // Проверка завершения инициализации if (err = hcSqlAllocConnect(&hdb) != 0) return err; // Создать соединение pdb = hdb; if (err = hcSqlConnect(pdb, pStrConnect, pStrLogin, pStrPassword) != 0) return err; //Установить связь с СУБД return err; } int HyTech::SqlQuery( char *pStrSql) /* Выполняем SQL-запрос */ { int err; int hOper ; unsigned int hcntOp ; if (err = hcSqlAllocStmt(pdb, &hOper) != 0) return err; // Создать оператор pOper = hOper ; if (err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) != 0) return err; // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях if (err = hcSqlExecDirect(pOper, pStrSql) != 0) return err; // Выполняем SQLзапрос if (err = hcSqlNumResultCols(pOper, &pCol) != 0) return err; // Получить количество колонок результата if (err = hcSqlRowCount(pOper, &pStr) != 0) return err; // Получить количество строк результата if (err = hcSqlOpenResults(pOper, &pRecSize) != 0) return err; // Открытие результатов для чтения infCol = new hcSqlDstInfoT[pCol]; // создаем структуру "Информация о колонках результата" if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &hcntOp) != 0) return err;// Получить информацию об операторе cntOp = hcntOp ; return err; } int HyTech::PasStr()/* Чтение результата */ { int err; static const size_t _n50 = 50; long position = 0 ; char** dataRes; dataRes = new char*[_n50]; for (int i = 0; i < pCol; ++i) dataRes[i] = new char[_n50]; char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, position, bufOut , pRecSize * _n50, &cntOut);// Чтение результатов char *p = bufOut ; // делаем указатель на буфер int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 1; ib <= nomRecBuf; ib++) // перебираем строки записанные в буфер { for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //dataRes[ib][j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ) ;// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dataRes[ib][j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dataRes[ib][j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } } for (int i = 0; i < pCol; ++i)// освобождаем память delete[] dataRes[i]; delete[] dataRes ; // освобождаем память delete[] bufOut ; // освобождаем память return 0; } int HyTech::CloseSqlQuery()/* Закрываем SQL-запрос */ { return hcSqlCloseResults(pOper); // Закрытие доступа к результатам } int HyTech::CloseConnectServer()/* Закрываем соединение отключаемся от сервера */ { int err; err = hcSqlFreeConnect(pdb); // Освободить соединение err = hcSqlDone(); // Завершение работы return err ; } файл main.cpp Скрытый текст #define HYCFG_WIN32 #include "HyTech.h" int main(int argc, char* argv[]) { int err; HyTech hT1 ; err = hT1.ConnectServer( "tcpip:/localhost:13000", "HTADMIN", "PASSWORD" ); std::cout << "ConnectServer err= " << err << std::endl; err = hT1.SqlQuery("fix all; select * from DOMA;"); std::cout << "SqlQuery err= " << err << std::endl; err = hT1.PasStr( ); std::cout << "PasStr err= " << err << std::endl; err = hT1.CloseSqlQuery(); std::cout << "CloseSqlQuery err= " << err << std::endl; err = hT1.CloseConnectServer(); std::cout << "CloseConnectServer err= " << err << std::endl; std::system("pause"); return 0; } Этот код работает , но все равно как то медленно подскажите по оптимизации, и самое главное я не могу понять как вывести из класса результат после того как err = hT1.PasStr( ); отработала результат остался в классе в переменной char** dataRes; вот а как вывести не знаю |
Сообщ.
#13
,
|
|
|
1.Несколько нехорошо называть pdb и pOper адресами, ибо это целые числа и в 64-битных случаях они не уместят в себе адреса.
2.Уберите вы кучу фигурных в case'ах - мешают восприятию. (но это - так, мелочи). 3.Ну и по-простому можно предоставить прямой доступ к dataRes в своём классе, хучь это и не комильфо: class HyTech { hcSqlDstInfoT *infCol; // Структура "Информация о колонках результата" static const size_t _n50 = 50; public: char** dataRes; // разрешаем прямой доступ :'( ... }; HyTech::HyTech() { infCol = NULL; dataRes = new char*[_n50]; for( int i = 0; i < _n50; i++) // по максимуму dataRes[i] = new char[_n50]; } HyTech::~HyTech() { if( infCol ) delete[] infCol; for( int i = 0; i < pCol; i++) // освобождаем память delete[] dataRes[i]; delete[] dataRes ; // освобождаем память } 4.Ну и соответственно в PasStr не заводим переменную dataRes и память в неё не выделяем и не освобождаем. 2,5 КБ = 50*50 не так и много, а?.. Ну а вообще у вас какая-то путаница: вы выделяли в dataRes столько строк (первый индекс массива) сколько колонок ("for (int i = 0; i < pCol; ++i) dataRes[i] = new char..."), а вот чуть позже уже бегаете с колонками по второму индексу: for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { ... dataRes[ib][j] = ... |
Сообщ.
#14
,
|
|
|
Цитата kms @ Cfon если я правильно понял посмотрев исходники по твоей ссылке получается что переменные надо прятать в private: да как правило надо в private или protected, а если надо получать к ним доступ извне, то создают функции-члены доступа к ним или делают дружественным класс, которому нужен доступ к членам этого класса. я как правило юзаю friend, не люблю писать функции-члены с именами Get и Set , но бывает нужно и это написать, например если надо вернуть ссылку или указатель вместо самого члена или сделать проверку значения перед установкой значения. но на самом деле я их в public сую , это не правильно. |
Сообщ.
#15
,
|
|
|
Цитата Славян @ 1.Несколько нехорошо называть pdb и pOper адресами, ибо это целые числа и в 64-битных случаях они не уместят в себе адреса. это взято из описания "API Клиентской части HyTech SQL сервера" , я понимаю там в зависимости от обращения pdb или &pdb там адрес или идентификатор соединения , я правильно трактую ? но это ладно ерунда , а как же быть с Цитата Славян @ ибо это целые числа и в 64-битных случаях они не уместят в себе адреса. Цитата Славян @ 2.Уберите вы кучу фигурных в case'ах - мешают восприятию. (но это - так, мелочи). ок, подправил , уже красивше стаало Цитата Славян @ 3.Ну и по-простому можно предоставить прямой доступ к dataRes в своём классе, хучь это и не комильфо: если так можно сделать чем это грозит , главное чтобы работало , или в смысле есть восможность что память выскочит или какой другой процесс поимеет доступ , в этом плане да ? Добавлено Цитата Славян @ 3.Ну и по-простому можно предоставить прямой доступ к dataRes в своём классе, хучь это и не комильфо: class HyTech { hcSqlDstInfoT *infCol; // Структура "Информация о колонках результата" static const size_t _n50 = 50; public: char** dataRes; // разрешаем прямой доступ ... }; HyTech::HyTech() { infCol = NULL; dataRes = new char*[_n50]; for( int i = 0; i < _n50; i++) // по максимуму dataRes[i] = new char[_n50]; } HyTech::~HyTech() { if( infCol ) delete[] infCol; for( int i = 0; i < pCol; i++) // освобождаем память delete[] dataRes[i]; delete[] dataRes ; // освобождаем память } да что то пошло не так сейчас перепроверяю, ошибка поперла , после того как прога отработала полность вывалилось исключение Необработанное исключение по адресу 0x5BD2615B (ucrtbased.dll) в ComPro1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCDCDCDBD. сейчас разбираюсь Добавлено да точно выбило как раз на for (int i = 0; i < pCol; i++) // освобождаем память delete[] dataRes[i]; на первоq i=0 Добавлено Цитата Славян @ 4.Ну и соответственно в PasStr не заводим переменную dataRes и память в неё не выделяем и не освобождаем. 2,5 КБ = 50*50 не так и много, а?. тут не чего не понял , память же под dataRes ты же выше написал в конструкторе, Добавлено Цитата Славян @ Ну а вообще у вас какая-то путаница: вы выделяли в dataRes столько строк (первый индекс массива) сколько колонок ("for (int i = 0; i < pCol; ++i) dataRes[i] = new char..."), а вот чуть позже уже бегаете с колонками по второму индексу: for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { ... dataRes[ib][j] = ... да точно ошибочка вышла , ошибка при очистке в место pCol надо pStr Добавлено все равно ошибка после выполнения Вызвано исключение по адресу 0x5C0B615B (ucrtbased.dll) в ComPro1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCDCDCDBD. Если для этого исключения имеется обработчик, выполнение программы может быть продолжено безопасно. я не правильно выделяю память под dataRes и не правильно ее заполняю , поэтому она и освобождается не правельно где не могу понять Добавлено Цитата Cfon @ да как правило надо в private или protected, а если надо получать к ним доступ извне, то создают функции-члены доступа к ним или делают дружественным класс, которому нужен доступ к членам этого класса. я как правило юзаю friend, не люблю писать функции-члены с именами Get и Set , но бывает нужно и это написать, например если надо вернуть ссылку или указатель вместо самого члена или сделать проверку значения перед установкой значения. да вот это надо попробовать , вот только как то надо продумать саму схему Добавлено вот примерно догнал но не до конца , нужен динамический массив 50 строк и динамически подставляется кол-во колонок pCol dataRes = new char*[N50]; // Делаем динамический буфер for (int i = 0; i < pCol; ++i) // dataRes[i] = new char[ Х ]; // вот так правельно будет или нет |