SWIG OpenSSL 1.0 - проблема с макросами STACK_OF
Вопрос
В предыдущих версиях OpenSSL это можно было сделать в файлах SWIG .i:
STACK *ssl_get_ciphers(SSL *ssl) {
return (STACK *)SSL_get_ciphers(ssl);
}
В OpenSSL 1.0.0beta3 это не удается, поскольку кажется, что STACK больше не определяется. Новый OpenSSL пытается лучше выполнять проверку типов, поэтому предполагается, что нужно использовать макрос STACK_OF, который определяется следующим образом:
#define STACK_OF(type) struct stack_st_##type
Если я изменю код выше, чтобы использовать STACK_OF:
STACK_OF(SSL_CIPHER) *ssl_get_ciphers(SSL *ssl) {
return SSL_get_ciphers(ssl);
}
Тогда SWIG не нравится:
Error: Syntax error in input(1).
Я могу получить вещи для компиляции, изменив это на:
struct stack_st_SSL_CIPHER *ssl_get_ciphers(SSL *ssl) {
return SSL_get_ciphers(ssl);
}
но это, очевидно, не очень хорошо, потому что OpenSSL может изменять макрос от выпуска к выпуску. Существует структура _STACK, но, опять же, это частная деталь OpenSSL, которая может меняться от выпуска к выпуску. Стеки также могут входить в качестве параметров, например:
int sk_x509_num(STACK_OF(X509) *stack) {
return sk_num(stack);
}
какой SWIG тоже не нравится.
Есть ли способ заставить это работать без использования личных данных OpenSSL?
Решение
После некоторого прочтения я выяснил, почему у меня возникла проблема, и как ее обойти. Проблема возникла из-за того, что препроцессор SWIG не знает о макросе STACK_OF, поэтому SWIG терпит неудачу. Я могу это исправить, добавив это в мой файл .i:
%include <openssl/safestack.h>
Теперь я столкнулся с той же проблемой с макросом LHASH_OF. К сожалению, он включен в lhash.h, который также включает stdio.h и т. Д., Который мне не нужен (и моя сборка фактически не может найти их так, как она настроена). Моя сборка нуждается в опции командной строки -includeall для swig. Так что, к сожалению, с LHASH_OF я в итоге скопировал определение из OpenSSL: (
#define LHASH_OF(type) struct lhash_st_##type
прямо под строкой% include, о которой я упоминал выше.
Другие советы
Можете ли вы создать свой собственный заголовок, который делает typedef следующим образом:
typedef t_stack_SSL_CIPHER STACK_OF(SSL_CIPHER)
Затем в .i файле сделайте
t_stack_SSL_CIPHER *ssl_get_ciphers(SSL *ssl) {
return SSL_get_ciphers(ssl);
}
... и получить заголовок # в нужном месте во время компиляции?