2009-02-03 7 views
10

Sooooo Я пишу интерпретатор скриптов. И в принципе, я хочу некоторые классы и функции, хранящиеся в DLL, но я хочу DLL искать функций в рамках программ, которые связываются с ним, как,Компиляция DLL с gcc

 program    dll 
---------------------------------------------------- 
send code to dll-----> parse code 
           | 
           v 
          code contains a function, 
          that isn't contained in the DLL 
           | 
list of functions in <------/ 
program 
     | 
     v 
corresponding function, 
user-defined in the 
program--process the 
passed argument here 
     | 
     \--------------> return value sent back 
          to the parsing function 

мне было интересно, в основном, как я составляю DLL с gcc? Ну, я использую порт windows gcc. Как только я скомпилирую DLL, содержащую мои классы и функции, как мне связать с ней мою программу? Как использовать классы и функции в DLL? Может ли функция вызова DLL из программы связываться с ней? Если я создаю объект класса {...}; в DLL, тогда, когда DLL загружается программой, объект будет доступен для программы? Заранее спасибо, мне действительно нужно знать, как работать с DLL на C++, прежде чем я смогу продолжить этот проект.

«Можете ли вы добавить более подробную информацию о том, почему вы хотите, чтобы DLL вызывала функции в основной программе?»

Я думал, что схема объясняет это ... программа, использующая DLL, передает фрагмент кода в DLL, который анализирует код, и если вызовы функций найдены в указанном коде, тогда соответствующие функции в DLL например, если я передал «a = sqrt (100)», то функция парсера DLL найдет вызов функции для sqrt(), а внутри DLL будет соответствующая функция sqrt(), которая будет вычислять квадрат корень аргумента, переданного ему, а затем он примет возвращаемое значение из этой функции и поместит его в переменную a ... как и любую другую программу, но если соответствующий обработчик для функции sqrt() не найден внутри DLL (будет список поддерживаемых изначально функций), тогда он будет вызывать аналогичную функцию, которая будет находиться внутри программы, используя DLL, чтобы увидеть, есть ли какие-то пользовательские функции этим именем.

Итак, скажем, вы загрузили DLL в программу, предоставляя вашей программе возможность интерпретировать сценарии этого конкретного языка, программа могла вызвать библиотеки DLL для обработки отдельных строк кода или передать им имена файлов скриптов для обработки ... но если вы хотите добавить команду в скрипт, который подходит для вашей программы, вы можете сказать, что в DLL задано логическое значение, указывающее, что вы добавляете функции на свой язык, а затем создаете функцию в своем коде, который будет отображаться функции, которые вы добавляете (DLL будет вызывать ее с именем функции, которую она хочет, если эта функция является определяемой пользователем, содержащейся в вашем коде, функция будет вызывать соответствующую функцию с аргументом, переданным ей с помощью DLL , вернуть возвращаемое значение пользовательской функции обратно в DLL, а если оно не существует, оно вернет код ошибки или NULL или s omething). Я начинаю видеть, что я должен найти другой способ обойти это, чтобы сделать вызовы функций идти в одну сторону только

+0

Ничего себе, я даже не знал, что есть победный порт gcc. Я бы попытался использовать gcc с окнами в качестве целевой платформы. – cbrulak

+0

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

+0

это называется mingw, или mingw32. Я думаю ... Я попытаюсь найти документацию gcc, но я довольно новичок в C и C++, поэтому некоторые его аспекты трудно понять. – user61721

ответ

-1

Вы всегда можете загрузить DLL во время выполнения с load library

+0

Хорошо, спасибо , Мне все еще трудно понять, как скомпилировать его, и как заставить DLL искать процедуры внутри программы, которая его вызывает, если это возможно – user61721

8

This link объясняет, как это сделать в основном.

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

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

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

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

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

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

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

+0

это немного над моей головой .. «Обычно, d создайте этот список вручную с помощью текстового редактора: «Как создать файл экспорта? Что такое cygwin dll?Могу ли я поместить классы в DLL? – user61721

2

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

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

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

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

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

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

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

  • Link все модули обмена памяти с DLL управления же памяти (как правило, с выполнения)
  • Убедитесь в том, что память выделяется и dealloccated только в тот же модуль.
  • выделить на стеке

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

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

parse(string, functions); 

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

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

// 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); 
0

Это звучит как работа для структур данных.

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

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++, создайте вместо него класс class, который содержит std :: vector или std :: map или что-то еще из ключевых слов и некоторых функций для их управления.

0

Winrawr, прежде чем идти дальше, прочитать эту первую:

Any improvements on the GCC/Windows DLLs/C++ STL front?

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

Смежные вопросы