Импорт функций C DLL в программу C ++ - PullRequest
4 голосов
/ 03 мая 2010

У меня есть сторонняя библиотека, написанная на C. Она экспортирует все свои функции в DLL.

У меня есть файл .h, и я пытаюсь загрузить DLL из моей программы на C ++.

Первое, что я попробовал, было окружение частей, где я включаю стороннюю библиотеку в

#ifdef __cplusplus
extern "C" {
#endif

и, в конце

#ifdef __cplusplus
} // extern "C"
#endif

Но проблема была в том, что все ссылки на функции DLL-файлов выглядели так в их заголовочных файлах:

a_function = (void *)GetProcAddress(dll, "a_function");

В то время как на самом деле a_function имел тип int (*a_function) (int *). Очевидно, компилятору MSVC ++ это не нравится, а компилятору MSVC, похоже, не против.

Итак, я прошел (жестокие пытки) и зафиксировал их все по образцу

typedef int (*_x_a_function) (int *); // using _a_function will not work, C uses it!
_x_a_function a_function ;

Затем, чтобы связать его с кодом DLL, в main ():

a_function = (_x_a_function)GetProcAddress(dll, "a_function");

Это, как кажется, делает компилятор НАМНОГО, НАМНОГО счастливее, но ОЧЕНЬ жалуется на этот последний набор из 143 ошибок, каждая из которых говорит для каждой попытки соединения с DLL:

error LNK2005: _x_a_function already defined in main.obj    main.obj

Многочисленные ошибки определения символов .. звучит как работа для extern! Поэтому я пошел и сделал ВСЕ объявления указателя функции следующим образом:

function_pointers.h

  typedef int (*_x_a_function) (int *);
  <b>extern</b> _x_a_function a_function ;

И в файле cpp:

function_pointers.cpp

  #include "function_pointers.h"
  _x_a_function a_function ;

ВСЕ нормально и модно .. за исключением ошибок компоновщика, теперь вида:

error LNK2001: unresolved external symbol _a_function main.obj

Main.cpp включает "function_pointers.h", поэтому он должен знать, где найти каждую из функций.

Я сбит с толку. Есть ли у кого-нибудь указатели, чтобы заставить меня функционировать? (Простите за каламбур ..)

Ответы [ 4 ]

2 голосов
/ 03 мая 2010

Ошибки компоновщика, подобные этой, предполагают, что вы определили все функции в function_pointers.cpp, но забыли добавить их в проект / make-файл.

Либо так, либо вы забыли "extern C", но и функции из function_pointers.cpp.

1 голос
/ 03 мая 2010

Когда вы связываете функции C, прототипы по умолчанию получают перед ними _, поэтому, когда вы делаете typedef с тем же именем

typedef int (*_a_function) (int *);
_a_function a_function

, вы получите проблемы, посколькуфункция в dll с именем _a_function.

1 голос
/ 03 мая 2010

Я полагаю, что если вы объявили typedefs и / или прототип как extern "C", вы должны помнить, что extern "C" также определяет это определение.

1 голос
/ 03 мая 2010

Обычно вы объявляете функцию в yourlibrary.h как extern "C" __declspec(dllexport) int __cdecl factorial(int);, а затем создаете эту функцию в yourlibrary.c:

extern "C" __declspec(dllexport) int __cdecl factorial(int x) {    
    if(x == 0)
        return 1;
    else
        return x * factorial(x - 1);
} 

После компиляции DLL вы получаете файлы .dll и .lib. Последний используется, когда вы хотите импортировать свои функции в проект. Вы помещаете #include "yourlibrary.h" и #pragma comment(lib, "yourlibrary.lib") в свой проект, после чего вы можете использовать int factorial(int) в своем приложении.

...