ошибка LNK2019 при импорте функций из DLL - PullRequest
0 голосов
/ 30 мая 2018

Я учусь собирать DLL и вызывать ее из другого проекта (я также хочу, чтобы DLL могла вызываться не только C / C ++, но и Python).Вот мой код для сборки DLL:

callbacktesetDLL.h:

#ifdef CALLBACKTESTDLL_EXPORTS
#define CALLBACKTESTDLL_API __declspec(dllexport)    
#else
#define CALLBACKTESTDLL_API __declspec(dllimport)
#endif

typedef int(CALLBACK *p)(char*);   

CALLBACKTESTDLL_API int __stdcall StrToInt(char*);      

CALLBACKTESTDLL_API char* __stdcall NumCompare(p FuncP, char*, int b);      

callbacktestDLL.cpp:

#include "stdafx.h"
#include <stdio.h>
#include "callbacktestDLL.h"
#include <stdlib.h>

CALLBACKTESTDLL_API int __stdcall StrToInt(char* StrInput)
{
    int IntResult;
    IntResult = atoi(StrInput);
    return IntResult;
}


CALLBACKTESTDLL_API char* __stdcall NumCompare(p FuncP, char* StrInput, int b)          
{
    int a = FuncP(StrInput);
    if (a>b)
    {
        return "a is bigger than b";
    }
    else
    {
        return "b is bigger than a";
    }
}

И файл Source.def:

LIBRARY

EXPORTS
StrToInt @1
NumCompare @2

С кодом выше я получил callbacktestDLL.dll и callbacktestDLL.libзависит , имена функций в DLL могут быть показаны: enter image description here

Теперь я хочу вызвать функции в DLL из другого проекта:

CallDLL.h:

#pragma comment(lib,"callbacktestDLL.lib")

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

typedef int(*p)(char*);

extern "C" _declspec(dllimport) int StrToInt(char* InpuString);
extern "C" _declspec(dllimport) char* NumCompare(p FuncP, char*, int b);

CallDLL.cpp:

#include "stdafx.h"

int main()
{
    p FuncP_R = StrToInt;
    NumCompare(FuncP_R, "1234", 40);
    return 0;
}

Однако, когда я запускаю проект, он сказал мне: error LNK2019: unresolved external symbol __imp__StrToInt и error LNK2019: unresolved external symbol __imp__NumCompare.Я уже скопировал файлы .lib и .dll в корневую папку проекта CallDLL.Почему это происходит?Как я могу решить это?Спасибо за внимание.

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

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

Существует небольшая разница между модулем, который реализует функции, к модулю, который использует функции.Разница составляет __declspec(dllimport) или __declspec(dllexport).Вот почему заголовочные файлы содержат

# ifdef CALLBACKTESTDLL_EXPORTS

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

Кстати: если вы определили CALLBACKTESTDLL_EXPORT, ваш макрос CALLBACKTESTDLL_API содержит __declspec(dllexport).Это заставляет компоновщик создать таблицу экспорта DLL..DEF не является необходимым.Вы должны удалить его, потому что ..... он снова определяет интерфейс (на другом уровне).

0 голосов
/ 30 мая 2018

Я наконец сделал это.Вот подробности: Файлы, которые генерируют DLL:

callbacktestDLL.h:

typedef int(CALLBACK *p)(char*);   

extern "C" __declspec(dllexport) int __stdcall StrToInt(char* InputString);     

extern "C" __declspec(dllexport) char* __stdcall NumCompare(p FuncP, char* InputString, int b); 

callbacktestDLL.cpp:

#include "stdafx.h"
#include <stdio.h>
#include "callbacktestDLL.h"
#include <stdlib.h>

extern "C" CALLBACKTESTDLL_API int __stdcall StrToInt(char* InputString)        
{
    int IntResult;
    IntResult = atoi(InputString);
    return IntResult;
}

extern "C" __declspec(dllexport) char* __stdcall NumCompare(p FuncP, char* InputString, int b)  
{
    int a = FuncP(InputString);
    if (a>b)
    {
        return "a is bigger than b\n";
    }
    else
    {
        return "b is bigger than a\n";
    }
}

По сравнению с предыдущими файлами в посте я удалил файл .def и добавил extern "C" перед каждым объявлением и определением функции.Затем я создаю новые файлы .dll и .lib и копирую их в корневую папку проектов CallDLL.Я использовал depends, чтобы увидеть имена функций в DLL: enter image description here

Я также изменил файл CallDLL следующим образом:

CallDLL.ч:

#pragma comment(lib,"callbacktestDLL")

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

typedef int(__stdcall *p)(char*); //same as typedef int(CALLBACK *p)(char*) in callbacktestDLL.h

extern "C" _declspec(dllimport) int __stdcall StrToInt(char* InputString); //exactly same as what's in callbacktestDLL.h apart from dllimport  
extern "C" _declspec(dllimport) char* __stdcall NumCompare(p FuncP, char* InputString, int b);  //exactly same as what's in callbacktestDLL.h apart from dllimport

CallDLL.cpp:

#include "stdafx.h"
    int main()
    {
        p FuncP_R;
        char* a = "1234";
        FuncP_R = StrToInt;
        printf(NumCompare(FuncP_R, a, 42));
        return 0;
    }

Работает как положено.Я думаю, что одна из ошибок, которые я сделал, отсутствует при импорте __stdcall.Может быть, есть и ошибки в названии искажения.Я продолжу проверять это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...