Почему временные файлы функции членства не связывают с правильным типом?

В первую очередь, будьте осторожны! Вся Ваша безопасность зависит от the… er… конфиденциальность из Вашего закрытые ключи. Keytool не имеет ключевого экспорта встроенным для предотвращения случайного раскрытия этого чувствительного материала, таким образом, Вы могли бы хотеть рассмотреть некоторые дополнительные гарантии, которые могли быть помещены на месте для защиты экспортируемых ключей.

Вот некоторый простой код, который дает Вам незашифрованный № 8 PKCS PrivateKeyInfo, который может использоваться OpenSSL (см. -nocrypt опция pkcs8 утилита ):

KeyStore keys = ...
char[] password = ...
Enumeration aliases = keys.aliases();
while (aliases.hasMoreElements()) {
  String alias = aliases.nextElement();
  if (!keys.isKeyEntry(alias))
    continue;
  Key key = keys.getKey(alias, password);
  if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
    /* Most PrivateKeys use this format, but check for safety. */
    try (FileOutputStream os = new FileOutputStream(alias + ".key")) {
      os.write(key.getEncoded());
      os.flush();
    }
  }
}

при необходимости в других форматах можно использовать KeyFactory для получения прозрачной ключевой спецификации для различных типов ключей. Тогда можно получить, например, частную экспоненту закрытого ключа RSA и произвести ее в нужном формате. Это сделало бы хорошую тему для последующего вопроса.

6
задан Matt Fichman 17 September 2009 в 18:05
поделиться

2 ответа

int main(int argc, char** argv) {
    void (Porsche::*ptr)(void) = &Porsche::Drive;
    Function(&Porsche::Drive, ptr);
    return 0;
}

ptr имеет тип void (Porsche :: *) () , но и Porsche :: Drive имеют тип void ( Car :: *) () (поскольку элемент находится в Car , а не в Porsche ). Таким образом, вызываемая функция сравнивает эти два указателя на элементы с этими типами, и в стандарте говорится

Кроме того, можно сравнивать указатели на члены или указатель на член и константу нулевого указателя. Преобразования указателей на члены (4.11) и квалификационные преобразования (4.4) выполняются для приведения их к общему типу. Если один операнд является константой нулевого указателя, общий тип - это тип другого операнда. В противном случае общий тип - это указатель на тип члена, аналогичный (4.4) типу одного из операндов, с сигнатурой cv-квалификации (4. 4), который является объединением cv-квалификационных сигнатур типов операндов.

4.11 описывает неявное стандартное преобразование из void (Base :: *) () в void (Derived :: *) () . Таким образом, сравнение обнаружит общий тип void (Porsche :: *) () . Для объекта типа Porsche оба указателя на член будут ссылаться на одну и ту же функцию (которая есть Car :: Drive ), поэтому сравнение даст истинное значение. Веб-компилятор comeau следует этой интерпретации и компилирует ваш код.

Для объекта типа Porsche оба указателя на член будут ссылаться на одну и ту же функцию (которая есть Car :: Drive ), поэтому сравнение даст истинное значение. Веб-компилятор comeau следует этой интерпретации и компилирует ваш код.

Для объекта типа Porsche оба указателя на член будут ссылаться на одну и ту же функцию (которая есть Car :: Drive ), поэтому сравнение вернет истину. Веб-компилятор comeau следует этой интерпретации и компилирует ваш код.

7
ответ дан 16 December 2019 в 21:43
поделиться

В g ++ 4.0.1 приведенные вами примеры компилируются нормально, но возникают проблемы со сравнением указателей на функции-члены разных типов (даже если сравниваемый элемент является виртуальным методом.

struct base
{
   void f() {}
   virtual void g() {}
};
struct derived : public base
{
   void f() {}
   virtual void g() {}
};
template <typename T, typename U>
bool cmp( void (T::*lhs)(), void (U::*rhs)() ) {
   return lhs == rhs;
}
int main()
{
   void (base::*bp)() = &base::f;
   void (base::*bvp)() = &base::g;

   cmp( bp, &base::f );  // compiles
   cmp( bvp, &base::g ); // compiles

   void (derived::*dp)() = &derived::f;
   void (derived::*dvp)() = &derived::g;

   cmp( dp, &derived::f );  // compiles
   cmp( dvp, &derived::g ); // compiles

   cmp( bp, dp );   // fails to compile
   cmp( bvp, dvp ); // fails to compile
}

Теперь я протестировал то же самое с онлайн-компилятором comeau, и весь код компилируется нормально. Я не могу сразу сказать вам, каково стандартное поведение. Мне придется некоторое время просматривать стандарт.

РЕДАКТИРОВАТЬ: Я думаю, что нет, litb уже сделал.

1
ответ дан 16 December 2019 в 21:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: