Компиляция DLL с gcc

Шаг 1: Добавить use strict и use warnings. Это выдает ошибки о необъявленных переменных.

Шаг 2: Добавить my, чтобы объявить $rlseHistRepo. Также добавьте my (%rlsSite, %rlsAuthor), чтобы объявить два хэша, используемых в вашем последнем цикле. Но это странно, так как вы читаете значения из этих хешей без всякого хранения в них данных. Это дает нам несколько ошибок «неинициализированного значения». Поэтому я думаю, что нам нужно переосмыслить вещи.

Идея состоит в том, чтобы создать один хэш для каждой записи. И когда запись заканчивается (когда мы получаем строку из тире), мы выводим эту запись. Примерно так:

my @keys = qw[Route Author Date Release Log
              Status Content Comment];

my %record;

while( ) {
  chomp;
  if (/-----/) {
    say OUTCSV join ',', @record{@keys};
    %record = ();
  }

  # ignore lines without a ':'
  next unless /:/;
  # ignore the '***' lines
  next if /\*\*\*/;

  my ($key, $value) = split /\s*:\s*/, 

Шаг 1: Добавить use strict и use warnings. Это выдает ошибки о необъявленных переменных.

Шаг 2: Добавить my, чтобы объявить $rlseHistRepo. Также добавьте my (%rlsSite, %rlsAuthor), чтобы объявить два хэша, используемых в вашем последнем цикле. Но это странно, так как вы читаете значения из этих хешей без всякого хранения в них данных. Это дает нам несколько ошибок «неинициализированного значения». Поэтому я думаю, что нам нужно переосмыслить вещи.

Идея состоит в том, чтобы создать один хэш для каждой записи. И когда запись заканчивается (когда мы получаем строку из тире), мы выводим эту запись. Примерно так:

[110]

Шаг 3: Очистить вещи, удалив несколько ненужных переменных и превратив их в фильтр Unix (чтение из STDIN и запись в STDOUT) - это на самом деле легче писать и делает вашу программу гораздо более гибкой.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my @keys = qw[Route Author Date Release Log
              Status Content Comment];

say "Site,Author,Release,Date,Version,Changes,Comment";
say ",,,,,,,";

my %record;

while (<>) {
  chomp;

  if (/-----/) {
    say join ',', @record{@keys};
    %record = ();
  }

  # ignore lines without a ':'
  next unless /:/;
  # ignore the '***' lines
  next if /\*\*\*/;

  if (my ($key, $value) = split /\s*:\s*/, 

Шаг 1: Добавить use strict и use warnings. Это выдает ошибки о необъявленных переменных.

Шаг 2: Добавить my, чтобы объявить $rlseHistRepo. Также добавьте my (%rlsSite, %rlsAuthor), чтобы объявить два хэша, используемых в вашем последнем цикле. Но это странно, так как вы читаете значения из этих хешей без всякого хранения в них данных. Это дает нам несколько ошибок «неинициализированного значения». Поэтому я думаю, что нам нужно переосмыслить вещи.

Идея состоит в том, чтобы создать один хэш для каждой записи. И когда запись заканчивается (когда мы получаем строку из тире), мы выводим эту запись. Примерно так:

[110]

Шаг 3: Очистить вещи, удалив несколько ненужных переменных и превратив их в фильтр Unix (чтение из STDIN и запись в STDOUT) - это на самом деле легче писать и делает вашу программу гораздо более гибкой.

[111]

Как уже упоминали другие, в производственном коде вы хотели бы использовать Text :: CSV для создания выходных данных.

, 2) { # Some keys have their values on the next line if ($value !~ /\S/) { chomp($value = <>); $value =~ s/^\s+//; } $record{$key} = $value; } }

Как уже упоминали другие, в производственном коде вы хотели бы использовать Text :: CSV для создания выходных данных.

, 2); # Some keys have their values on the next line if ($value !~ /\S/) { chomp($value = ); $value =~ s/^\s+//; } $record{$key} = $value; }

Шаг 3: Очистить вещи, удалив несколько ненужных переменных и превратив их в фильтр Unix (чтение из STDIN и запись в STDOUT) - это на самом деле легче писать и делает вашу программу гораздо более гибкой.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my @keys = qw[Route Author Date Release Log
              Status Content Comment];

say "Site,Author,Release,Date,Version,Changes,Comment";
say ",,,,,,,";

my %record;

while (<>) {
  chomp;

  if (/-----/) {
    say join ',', @record{@keys};
    %record = ();
  }

  # ignore lines without a ':'
  next unless /:/;
  # ignore the '***' lines
  next if /\*\*\*/;

  if (my ($key, $value) = split /\s*:\s*/, 

Шаг 1: Добавить use strict и use warnings. Это выдает ошибки о необъявленных переменных.

Шаг 2: Добавить my, чтобы объявить $rlseHistRepo. Также добавьте my (%rlsSite, %rlsAuthor), чтобы объявить два хэша, используемых в вашем последнем цикле. Но это странно, так как вы читаете значения из этих хешей без всякого хранения в них данных. Это дает нам несколько ошибок «неинициализированного значения». Поэтому я думаю, что нам нужно переосмыслить вещи.

Идея состоит в том, чтобы создать один хэш для каждой записи. И когда запись заканчивается (когда мы получаем строку из тире), мы выводим эту запись. Примерно так:

[110]

Шаг 3: Очистить вещи, удалив несколько ненужных переменных и превратив их в фильтр Unix (чтение из STDIN и запись в STDOUT) - это на самом деле легче писать и делает вашу программу гораздо более гибкой.

[111]

Как уже упоминали другие, в производственном коде вы хотели бы использовать Text :: CSV для создания выходных данных.

, 2) { # Some keys have their values on the next line if ($value !~ /\S/) { chomp($value = <>); $value =~ s/^\s+//; } $record{$key} = $value; } }

Как уже упоминали другие, в производственном коде вы хотели бы использовать Text :: CSV для создания выходных данных.

11
задан user61721 3 February 2009 в 01:43
поделиться

5 ответов

Эта ссылка объясняет, как сделать это основным способом.

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

При нормальном создании статической библиотеки существует минимум липкой вещи и получений по запросу компоновщика в коде, это нуждается и повторно упаковывает его для Вас в Вашем исполняемом файле.

В dll Вы на самом деле добираетесь, два конечных продукта (три действительно - просто ожидают): dll и тупиковая библиотека. Тупик является статической библиотекой, которая точно походит на Вашу обычную статическую библиотеку, за исключением того, что вместо того, чтобы выполнить Ваш код, каждый тупик обычно является командой перехода к общей стандартной программе. Общая стандартная программа загружает Ваш dll, получает адрес стандартной программы, которую Вы хотите назвать, затем исправляет исходную команду перехода для движения туда поэтому, когда Вы называете его снова, Вы заканчиваете в своем dll.

Третий конечный продукт обычно является заголовочным файлом, который говорит Вам всем о типах данных в Вашей библиотеке.

Таким образом, Ваши шаги: создайте свои заголовки и код, создайте dll, создайте тупиковую библиотеку из списка заголовков/кода/некоторых экспортируемых функций. Код конца свяжется с тупиковой библиотекой, которая загрузит dll и согласует таблицу переходов.

Липкая вещь компилятора/компоновщика включает вещи как проверка, что библиотеки времени выполнения - то, где они необходимы, удостоверяясь, что статические конструкторы выполняются, удостоверяясь, что статические деструкторы регистрируются для более позднего выполнения, и т.д., и т.д., и т.д.

Теперь относительно Вашей основной проблемы: как я пишу расширяемый код в dll? Существует много возможных путей - типичный путь состоит в том, чтобы определить чистый абстрактный класс (иначе интерфейс), который определяет, поведение и или передает это в стандартной программе обработки или создать стандартную программу для регистрации интерфейсов, чтобы сделать работу, затем стандартная программа обработки просит у регистратора объект обработать обрабатываемую деталь для него.

8
ответ дан 3 December 2019 в 10:45
поделиться

В детали того, что Вы планируете решить, возможно, необходимо посмотреть на растяжимый синтаксический анализатор как lua вместо того, чтобы создать собственное.

К Вашему более определенному фокусу.
DLL (обычно?) означал быть завершенным в и себя или явно знать что другие библиотеки использовать для завершения себя.

Под чем я подразумеваю то есть, Вам не могло предоставить метод неявно вызывающее приложение для завершения функциональности DLLs.

Вы могли однако сделать часть своего API условием методов из приложения вызова, таким образом делая DLL полностью содержавшим и передача знания явный.

Как я использую классы и функции в DLL?
Включайте заголовки в свой код, когда модуль (exe или другой dll) связан, dlls проверяются на completness.

DLL может вызвать функции из программы, связывающейся с ним?
Да, но это должно быть сказано о них во время выполнения.

Если я делаю класс {...} Объект; в DLL, затем когда DLL будет загружен программой, объект будет доступен программе?
Да это будет доступно, однако существуют некоторые ограничения, о которых необходимо знать. Такой как в области управления памятью это важно для также:

  • Свяжите все модули, совместно использующие память с тем же управлением памятью dll (обычно c время выполнения)
  • Удостоверьтесь, что память выделена и освобождена только в том же модуле.
  • выделите на стеке

Примеры!
Вот основная идея передать функции dll, однако в Вашем случае может не быть самым полезным, поскольку необходимо знать впереди, что другие функции Вы хотите обеспеченный.

// parser.h
struct functions {
  void *fred (int );
};

parse( string, functions );

// program.cpp
parse( "a = sqrt(); fred(a);", functions );

То, в чем Вы нуждаетесь, является способом зарегистрировать функции (и их детали с dll.) Большей проблемой здесь является бит деталей. Но перескакивание через это, Вы могли бы сделать что-то как wxWidgets, делает с регистрацией класса. Когда method_fred будет создан Вашим приложением, это вызовет конструктора и зарегистрируется в dll посредством использования от methodInfo. Синтаксический анализатор может поиск methodInfo для доступных методов.

// parser.h
class method_base { };
class methodInfo {
   static void register(factory);
   static map<string,factory> m_methods;
}

// program.cpp
class method_fred : public method_base {
   static method* factory(string args);
   static methodInfo _methoinfo;
}
methodInfo method_fred::_methoinfo("fred",method_fred::factory);
2
ответ дан 3 December 2019 в 10:45
поделиться

Это походит на задание для структур данных.

Создайте структуру, содержащую Ваши ключевые слова и функцию, связанную с каждым.

struct keyword {
    const char *keyword;
    int (*f)(int arg);
};

struct keyword keywords[max_keywords] = {
    "db_connect", &db_connect,
}

Затем запишите функцию в своем DLL, к которому Вы передаете адрес этого массива:

plugin_register(keywords);

Затем в DLL это может сделать:

keywords[0].f = &plugin_db_connect;

С этим методом код для обработки ключевых слов сценария остается в основной программе, в то время как DLL управляет структурами данных для называния его собственных функций.

При взятии его к C++ сделайте структуру классом вместо этого, который содержит станд.:: вектор или станд.:: отобразитесь или безотносительно ключевых слов и некоторых функций для управления ими.

0
ответ дан 3 December 2019 в 10:45
поделиться

Winrawr перед продолжением читают это сначала:

Какие-либо улучшения на GCC/WINDOWS DLLS/C ++ передняя сторона STL?

В основном можно столкнуться с проблемами, когда передающий STL представляет в виде строки вокруг DLLs, и можно также испытать затруднения за исключениями, летящими через границы DLL, хотя это не что-то, что я испытал (все же).

0
ответ дан 3 December 2019 в 10:45
поделиться

Вы могли всегда загружать dll во времени выполнения с библиотекой загрузки

-2
ответ дан 3 December 2019 в 10:45
поделиться
Другие вопросы по тегам:

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