Скомпилируйте DLL в C / C ++, затем вызовите ее из другой программы

Да, если в аннотации Column есть сохранение времени выполнения

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
    ....
}

, вы можете сделать что-то вроде этого

for (Field f: MyClass.class.getFields()) {
   Column column = f.getAnnotation(Column.class);
   if (column != null)
       System.out.println(column.columnName());
}
56
задан Carson Myers 11 May 2009 в 11:27
поделиться

5 ответов

Что касается сборки DLL с использованием MinGW, вот несколько очень кратких инструкций.

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

__declspec( dllexport ) int add2(int num){
   return num + 2;
}

, затем, если ваши функции находятся в файле с именем funcs.c, вы можете их скомпилировать:

gcc -shared -o mylib.dll funcs.c

Флаг -shared сообщает gcc о необходимости создания DLL.

Чтобы проверить, действительно ли DLL экспортировала функции, возьмите бесплатный инструмент Dependency Walker и используйте его для проверки DLL.

Для бесплатной IDE, которая автоматизирует все флаги и т. Д. ., необходимые для создания DLL, взгляните на отличный Code :: Blocks , который очень хорошо работает с MinGW.

Edit: Для более подробной информации по этому вопросу,

25
ответ дан 24 November 2019 в 19:10
поделиться

Вот как вы это делаете:

В .h

#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

extern "C" // Only if you are using C++ rather than C
{    
  EXPORT int __stdcall add2(int num);
  EXPORT int __stdcall mult(int num1, int num2);
}

в .cpp

extern "C" // Only if you are using C++ rather than C
{    
EXPORT int __stdcall add2(int num)
{
  return num + 2;
}


EXPORT int __stdcall mult(int num1, int num2)
{
  int product;
  product = num1 * num2;
  return product;
}
}

Макрос сообщает вашему модулю (т.е. вашим файлам .cpp), что они предоставляют dll вещи во внешний мир. Люди, которые внедряют ваш файл .h, хотят импортировать те же функции, поэтому они продают EXPORT как указание компоновщику импортировать. Вам нужно добавить BUILD_DLL к параметрам компиляции проекта, и вы можете захотеть переименовать его во что-то явно специфичное для вашего проекта (в случае, если dll использует вашу dll).

Вам также может потребоваться создать .def файл, чтобы переименовать функции и де-запутать имена (C / C ++ искажает эти имена). Эта запись в блоге может быть интересной отправной точкой по этому поводу.

Загрузка собственных пользовательских библиотек DLL аналогична загрузке системных библиотек DLL. Просто убедитесь, что DLL находится на вашем системном пути. C:

7
ответ дан 24 November 2019 в 19:10
поделиться

Есть только одно отличие. Вы должны позаботиться о том, чтобы победить C ++. Но на окнах нужно позаботиться о 1) удаление функций, которые нужно экспортировать из DLL 2) напишите так называемый файл .def, в котором перечислены все экспортируемые символы.

В Windows при компиляции DLL необходимо использовать

__ declspec (dllexport)

, но при его использовании необходимо написать __declspec (dllimport)

Обычный способ сделать это что-то вроде

#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

Именование немного сбивает с толку, потому что его часто называют EXPORT .. Но это то, что вы где-то найдете в большинстве заголовков. Итак, в вашем случае вы должны написать (с указанным выше #define)

int DLL_EXPORT add .... int DLL_EXPORT mult ...

Помните, что вы должны добавить директиву препроцессора BUILD_DLL во время сборки разделяемой библиотеки.

С уважением. Фридрих

6
ответ дан 24 November 2019 в 19:10
поделиться

При написании dll на C ++ нужно остерегаться изменения имени. Если вам нужна функциональная совместимость между C и C ++, вам лучше экспортировать неискаженные функции в стиле C из dll.

У вас есть два варианта использования dll

  • Либо использовать файл lib для связывания символов - динамическое связывание во время компиляции
  • Используйте LoadLibrary () или какую-либо подходящую функцию для загрузки библиотеки , получите указатель на функцию ( GetProcAddress ) и вызовите его - динамическое связывание во время выполнения

Однако экспорт классов не будет работать, если вы воспользуетесь вторым методом.

4
ответ дан 24 November 2019 в 19:10
поделиться

Для VB6:

Вам необходимо объявить свои функции C как __stdcall, иначе вы получите ошибки типа «недопустимое соглашение о вызовах». По поводу других ваших вопросов:

могу ли я принимать аргументы по указателю / ссылке из внешнего интерфейса VB?

Да, использовать модификаторы ByRef / ByVal.

Может ли DLL вызывать теоретическую функцию во внешнем интерфейсе?

Да, используйте оператор AddressOf. Перед этим вам нужно передать указатель функции в dll.

Или функция может взять «указатель на функцию» (я даже не знаю, возможно ли это) из VB и вызвать его?)

Да, используйте оператор AddressOf.

update (появилось больше вопросов :)):

, чтобы загрузить его в VB, я просто использую обычный метод (что бы я сделал, чтобы загрузить winsock.ocx или другую среду выполнения, но вместо этого найдите мою DLL) или я могу поместить вызов API в модуль?

Вам нужна функция API декалера в коде VB6, например:

Private Declare Function SHGetSpecialFolderLocation Lib "shell32" _
   (ByVal hwndOwner As Long, _
    ByVal nFolder As Long, _
    ByRef pidl As Long) As Long
3
ответ дан 24 November 2019 в 19:10
поделиться