Обновить

Комментарии 10

Показательно, насколько меньше писанины на Паскале :)
Меньше? Модуль на паскале — 15 строк кода, считая заголовочный файл. Модуль на си — 10 строк, включая ненужные проверки типа #ifdef __cplusplus (если мы точно собираем сишным компилятором, этот дефайн не будет выставлен и экстерн нам не нужен тоже).
Если речь идет о загрузке в отдельном процессе, нет смысла в DLL/SO.

Тогда правильнее запускать процессы и использовать любой вариант IPC.
Для того, чтобы студенты смогли использовать IPC сами, им необходимы какие-то дополнительные телодвижения (изучение протокола передачи данных, например). Это также приведёт к дублированию функционала, отвечающего за IPC в различных реализациях, сложности синхронизации исправленных ошибок…
В оригинале IPC используется между загрузчиком библиотек и Java-программой (соответственно, загрузчик — это отдельный процесс), а первый плагин пишется также просто, как этот «Hello, world».
В любом случае что-то изучать придется.

В вашем случае надо изучить mangling etc.

В случае IPC, — изучить API любой библиотеки IPC.
А вы можете привести пример библиотеки IPC, доступной хотя бы для двух платформ — Linux и Windows и на 2-х языках: Pascal, C/C++?
На странице привязок Object Pascal отсутствует, но его можно найти тут: delphimax.wordpress.com/2010/09/03/%C3%B8mq-for-delphi/

У нас использовались уже привязки к Objective C и к Ruby, нареканий нет.
Благодарю за наводку, будет альтернативой :).

Возможно, вот эту функцию можно написать лучше

#include "loader.h"
#include "functions.h"
#include <stdio.h>

#ifndef WIN32
#include <dlfcn.h>
#else
#include <windows.h>
#endif

void loadRun(const char * const s) {
   void * lib;
   void (*fun)(void);
#ifndef WIN32
   lib = dlopen(s, RTLD_LAZY);
#else
   lib = LoadLibrary(s);
#endif
   if (!lib) {
     printf("cannot open library '%s'\n", s);
     return;
   }
#ifndef WIN32
   fun = (void (*)(void))dlsym(lib, "run");
#else
   fun = (void (*)(void))GetProcAddress((HINSTANCE)lib, "run");
#endif
   if (fun == NULL) {
     printf("cannot load function run\n");
   } else {
     fun();
   }
#ifndef WIN32
   dlclose(lib);
#else
   FreeLibrary((HINSTANCE)lib);
#endif
}

Например, вот так

#include "loader.h"
#include "functions.h"
#include <stdio.h>

#ifdef WIN32
#include <windows.h>
#define OPEN(PATH) LoadLibrary(PATH)
#define GETFN(LIB, FN) GetProcAddress((HINSTANCE) LIB, FN)
#define CLOSE(LIB) FreeLibrary((HINSTANCE) LIB)

#elifdef UNIX
// Не помню правильный заголовок,
// но UNIX-подобные содержит POSIX-совместимые заголовки,
// к которым относятся dlfcn.h
#include <dlfcn.h>
#define OPEN(PATH) dlopen(PATH, RTLD_LAZY)
#define GETFN(LIB, FN) dlsym(LIB, FN)
#define CLOSE(LIB) dlclose(LIB)
#endif

void loadRun(const char * const s) {
   void * lib;
   void (*fun)(void);
   lib = OPEN(s);
   if (!lib) {
     printf("cannot open library '%s'\n", s);
     return;
   }
   fun = (void (*)(void))GETFN(lib, "run");
   if (fun == NULL) {
     printf("cannot load function run\n");
   } else {
     fun();
   }
   CLOSE(lib);  
}

P. S. Я вообще разделил реализацию и просто выбираю правильную в CMake.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации