Страницы

Поиск по вопросам

среда, 27 февраля 2019 г.

Передача массива из функции

Бинарный файл составляю из 2 source-файлов, в одном основной код, в другой функции генерации ssl-сертификата. Функция формирования сертификата (дополнительные функции не привожу) из второго файла.
int create_cert(unsigned char *buf, int *len) { BIO *bio_err; X509 *x509=NULL; EVP_PKEY *pkey=NULL; unsigned char *p; int i;
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); mkcert(&x509,&pkey,2048,0,1490);
*len=i2d_X509(x509,NULL); buf=malloc(*len); if (buf==NULL) return -1; p=buf; i2d_X509(x509,&p);
X509_free(x509); EVP_PKEY_free(pkey); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif CRYPTO_cleanup_all_ex_data(); CRYPTO_mem_leaks(bio_err); BIO_free(bio_err);
return 1; }
Тут я генерирую сертификат средствами openssl, с помощью i2d_X509 перевожу в DER-формат и записываю в память под указателем buf (а так же размер массива сертификата), который должен возвратиться туда где я вызываю эту функцию (т.е. в основной файл).
А вот главная функция первого файла.
int main(void) { char Cert; unsigned char *cbCertificate; int certLen;
create_cert(&cbCertificate,&certLen); }
Тут я принимаю указатель и размер массива сертификата с предыдущей функции. Все никак не могу понять как можно взять массив из памяти и присвоить его в переменную Cert, чтобы после передать другой функции. Я попытался записать сертификат в файл с помощью
FILE *fp=fopen("cert.cer","w"); if (fp!=NULL) { fwrite(&cbCertificate,1,certLen,fp); fclose(fp); }
Записывается всякая хрень. Я понимаю что cbCertificate это указатель на указатель. Я понимаю как можно взять адрес указателя, но вот к данным получить доступ не понимаю как.


Ответ

Если я правильно Вас поняла, и Вы хотите вернуть из внутренней функции наружу выделенный внутри нее массив, используя в качестве параметра этой функции двойной указатель, то, для начала, нужно описать в параметрах этой функции двойной указатель
int create_cert(unsigned char **buf, int *len){...}
Далее, выделять память под массив Вам нужно с учетом, что вы используете двойной указатель (Вы аналогично уже работаете с len):
*buf = (unsigned char *)malloc(*len);
Тогда, после вывова функции create_cert() в cbCertificate будет лежать указатель на новый, выделенный внутри create_cert() массив.
Все никак не могу понять как можно взять массив из памяти и присвоить его в переменную Cert
Так, как у Вас описано, это точно не получится, так как переменная Cert у вас имеет тип char, - т.е. 1 элемент. Нельзя одному элементу типа char присвоить весь массив.
Если же Вы, после того, как получили с помощью функции create_cert() данные, хотите записать их в файл, то запись будет выглядеть вот так :
fwrite(cbCertificate,1,certLen,fp);
так как
unsigned char *cbCertificate;
это не двойной, а обычный указатель. Вот когда вы берете его адрес, как здесь :
create_cert(&cbCertificate,&certLen);
внутри функции create_cert() получается двойной указатель.
UPD: Как выглядят двойные указатели:
Объявление :
int **cbCertificate;
Тогда инициализация такого указателя может выглядеть вот так :
int a = 0; int *ptr = &a; int **cbCertificate = &ptr;
И передавать такой двойной указатель в функцию можно будет вот так :
void foo(int ** pptr){...} ... int main(){ int a = 0; int *ptr = &a; int **cbCertificate = &ptr;
foo(cbCertificate); }
Если же двойной указатель нам нужен только для того, чтобы вернуть из функции адрес выделенного внутри этой функции буффера, то можно обойтись использованием двойного указателя только на стеке функции, тогда вышеприведенный пример можно записать так :
void foo(int ** pptr){...} ... int main(){ int a = 0; int *ptr = &a;
foo(&ptr); }
Двойной указатель является не чем иным, как адресом некоторого указателя, следовательно, работать с самим указателем и данными внутри функции foo() можно следующим образом:
void foo(int **pptr){ ... *pptr = NULL; // инициализация указателя, адрес котрого хранится в pptr //(pptr все еще хранит значение, указывающее на некоторую ячейку памяти, //а вот эта самая память уже никуда не указывает) *pptr = (int *)malloc(10*sizeof(int)); // ячейка, на которую указывает // pptr, указывает на массив из 10 значений типа int
(*pptr)[0] = 5; // инициализируем первый элемент выделенного массива ... }

Комментариев нет:

Отправить комментарий