#include "stdafx.h"
#include <stdio.h>
__declspec(dllexport) int testproc(int i, char* str)
{
printf(str);
return 0;
}
dll c++ и неявное связывание (implicit linking)
Код mydll.cpp
Код:
Потом пытаюсь в приложении достать эту функцию из dll.
Код application.cpp
Код:
#include "stdafx.h"
#include <conio.h>
#include "C:\\Documents and Settings\Inc(Dec(i))\Мои документы\Visual Studio 2008\Projects\mydll\mydll\mydll.h"
int _tmain(int argc, _TCHAR* argv[])
{
testproc(5,"test");
_getch();
return 0;
}
#include <conio.h>
#include "C:\\Documents and Settings\Inc(Dec(i))\Мои документы\Visual Studio 2008\Projects\mydll\mydll\mydll.h"
int _tmain(int argc, _TCHAR* argv[])
{
testproc(5,"test");
_getch();
return 0;
}
Пытаюсь собрать прогу и запустить ее, на что компилятор ругается:
Error 1 error LNK2019: unresolved external symbol "int __cdecl testproc(int,char *)" (?testproc@@YAHHPAD@Z) referenced in function _wmain application.obj
Error 2 fatal error LNK1120: 1 unresolved externals C:\Documents and Settings\Inc(Dec
Что я забыл, или делаю не так? Хэлп плиз.
Сразу назревают вопросы:
"А точка входа у нее есть?"
"А вы гугл мучали?"
"А здесь: http://en.wikipedia.org/wiki/Dynamic-link_library для начала смотрели?"(тут есть нормальный пример, чтоб разобраться)
и многие-многие другие вопросы. Но для начала хотелось бы убедиться что вы изучили хоть какую-либо литературу.
Просто добавь .lib сгенерированный при компиляции dll-ки в additional dependences в свойствах линкера при компоновке экзешки:)
или директивой прагма:
Код:
#pragma comment (lib, "..\\debug\\dll_test.lib")
в пути соответственно путь к твоему либу
заголовок из твоей библиотеки тоже подключать необязательно, можно сделать вот так:
Код:
#include <conio.h>
#include <tchar.h>
#pragma comment (lib, "..\\debug\\dll_test.lib")
extern int testproc(int, char*);
int _tmain(int argc, _TCHAR* argv[])
{
testproc(5,"test");
_getch();
return 0;
}
#include <tchar.h>
#pragma comment (lib, "..\\debug\\dll_test.lib")
extern int testproc(int, char*);
int _tmain(int argc, _TCHAR* argv[])
{
testproc(5,"test");
_getch();
return 0;
}
P.S. Не забудь, положить .dll-ку, в папку с экзешкой или в папки PATH (windows, system32, ...)
alt@zir спасибо, заработало.
Цитата: alt@zir
Вполне работоспособный пример:)
Просто добавь .lib сгенерированный при компиляции dll-ки в additional dependences в свойствах линкера при компоновке экзешки:)
Просто добавь .lib сгенерированный при компиляции dll-ки в additional dependences в свойствах линкера при компоновке экзешки:)
хм... а зачем тогда сама dll-ка?
вся реализация в либе уже будет
P.S. Вроде как __declspec не из стандарта C++, а чисто микрософтовая приблуда...
Блин начал делать нормальную dll'ку (не учебную), опять подобная ошибка((( хотя все вроде делаю так же: либу подключаю, делаю импорт... Подскажите, чем еще может быть вызвана подобная ошибка?
Такие либы называются библиотеки импорта, код функций в них не содержится, а данные оттуда используются для построения секции импорта в формате PE. Генерируются они компоновщиком, cтатические библиотеки собираются же библиотекарем(в MSVC). При явной(explicit) загрузке библиотеки импорта не нужны.
В стандарте нет, но удобно:) хотя я кроме noinline и dllexport, ничего не использую.
Error 1 error LNK2019: unresolved external symbol __imp__addLast referenced in function _wmain lab6.obj
Error 2 fatal error LNK1120: 1 unresolved externals
ты классы используешь? приведи код библиотеки и экзешки
Проект в данный момент выглядит так:
Загловочный файл от dll'ки:
Код:
#ifndef MYLIBAPI
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
struct List
{
char* data; //указатель на данные
List* next; //указатель на следующий элемент
};
MYLIBAPI void addLast(List** list, char* data);
MYLIBAPI void printList(List* list);
MYLIBAPI void writeList(char* fname, List* plst);
MYLIBAPI List* readList(char* fname);
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
struct List
{
char* data; //указатель на данные
List* next; //указатель на следующий элемент
};
MYLIBAPI void addLast(List** list, char* data);
MYLIBAPI void printList(List* list);
MYLIBAPI void writeList(char* fname, List* plst);
MYLIBAPI List* readList(char* fname);
Исходный код dll'ки:
Код:
#define MYLIBAPI extern "C" __declspec(dllexport)
#include "stdafx.h"
#include "lab6_dll.h" //подключаем выше описанный h-файл
#include <windows.h>
#include <conio.h>
#include <stdio.h>
//добавление нового элемента в конец списка
void addLast(List** list, char* data)
{
...
}
//Просмотр списка
void printList(List* list)
{
...
}
//Сохранение списка в файл
void writeList(char* fname, List* plst)
{
...
}
//Чтение списка из файла
List* readList(char* fname)
{
...
}
#include "stdafx.h"
#include "lab6_dll.h" //подключаем выше описанный h-файл
#include <windows.h>
#include <conio.h>
#include <stdio.h>
//добавление нового элемента в конец списка
void addLast(List** list, char* data)
{
...
}
//Просмотр списка
void printList(List* list)
{
...
}
//Сохранение списка в файл
void writeList(char* fname, List* plst)
{
...
}
//Чтение списка из файла
List* readList(char* fname)
{
...
}
Исходный код проги, которая использует dl:
Код:
#pragma comment (lib, "C:\\Documents and Settings\\Inc(Dec(i))\\Мои документы\\Visual Studio 2008\\Projects\\OS_Tarasov\\Debug\\lab6_dll.lib")
#include "stdafx.h"
#include "C:\\Documents and Settings\\Inc(Dec(i))\\Мои документы\\Visual Studio 2008\\Projects\\OS_Tarasov\\lab6_dll\\lab6_dll.h"
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[])
{
List* head = NULL;
addLast(&head,"first");
_getch();
return 0;
}
#include "stdafx.h"
#include "C:\\Documents and Settings\\Inc(Dec(i))\\Мои документы\\Visual Studio 2008\\Projects\\OS_Tarasov\\lab6_dll\\lab6_dll.h"
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[])
{
List* head = NULL;
addLast(&head,"first");
_getch();
return 0;
}
У тебя из дллки не экспортируется не одной функции, насколько я понял ты хотел использовать один заголовок и для экзешки и для библиотеки:) если да то исправь дифайн в в cpp файле дллки на MYLIBAPI
Да так и задумывалось))). Не понял тебя, где что исправить? В экзешке вообще нет дефайна.
тогда просто напишы в заголовочном файле че-нить вроде
#ifdef BUILD_EXE
... __declspec(dllimport) ...
#else
... __declspec(dllexport) ...
#endif
ну и соответсвенно подключая длл в екзе пишы там
#define BUILD_EXE
вроде так :)
Народ, ну помогите плз, неужели никто dll не использует?
Уииии!!!! Более не актуально, оказывается надо было поменять местами 2 строчки. Сначала надо было делать #include а потом #pragma, а не наоборот. Какой в этом смысл правда я так и не понял, какая-то особенность VS прям...