Ошибка LNK2019 и фатальная ошибка LNK1120: 2 неразрешенных внешних кода
Я знаю, что мой вопрос и его ответ существуют где угодно на сайте, но у меня есть больше, чем он.
У меня есть библиотека zip, и я использую ее в другом проекте C++.
Библиотека Zip: czip.h
#ifndef _CZIP_H_
#define _CZIP_H_
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <windows.h>
#include <sys\stat.h>
#include <stdio.h>
#ifndef DLL_INTERNAL
#define DLL_INTERNAL __declspec( dllimport )
#endif
class DLL_INTERNAL CZipException
{
public:
CZipException( const char*fm, ... );
const char* GetString() { return m_sMessage; }
protected:
char m_sMessage[ 128 ];
};
// pure virtual
class DLL_INTERNAL CMamaZip
{
public:
CMamaZip( const char *sSourceFileName );
void SwapSize( const char *sTargetFileName );
protected:
virtual int HardWork( int inFile, int outFile ) = 0;
char m_sSourceFileName[ MAX_PATH ];
char *m_sOperation;
};
class DLL_INTERNAL CZip : public CMamaZip
{
public:
CZip( const char *sSourceFileName );
protected:
virtual int HardWork( int inFile, int outFile );
};
class DLL_INTERNAL CUnzip : public CMamaZip
{
public:
CUnzip( const char *sSourceFileName );
protected:
virtual int HardWork( int inFile, int outFile );
};
#endif // _CZIP_H_
czip.cpp:
#define DLL_INTERNAL __declspec( dllexport )
#include "czip.h"
#include "tailor.h"
// global variables instancied in gzip
extern "C" {
extern int dozip( int, int);
extern int dounzip( int, int );
extern long time_stamp;
extern char ifname[MAX_PATH_LEN];
extern int save_orig_name;
extern int ifd;
extern int ofd;
}
int inFile, outFile;
// this function is called by gzip when there is an error
// instead of doing an exit( .. )
extern "C" void do_exit_dll(int exitcode)
{
close( inFile );
close( outFile );
throw( CZipException( "problem with zipping/unzipping operation : %d", exitcode ) );
}
CZipException::CZipException( const char* fm, ... )
{
char *p = m_sMessage;
va_list args;
va_start( args, fm );
p += vsprintf( p, fm, args);
va_end( args );
}
int WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
return 1;
}
CMamaZip::CMamaZip( const char *sUnzippedFileName )
{
strcpy( m_sSourceFileName, sUnzippedFileName );
}
// throw CZipException
void CMamaZip::SwapSize( const char *sTargetFileName )
{
if (strcmp(m_sSourceFileName,sTargetFileName)==0)
throw ( CZipException( "target name must be different than source name" ) );
// try to open in unzipped file
if ( ( inFile = open( m_sSourceFileName, _O_BINARY | _O_RDONLY ) ) == -1 )
throw ( CZipException( "unable to open source file" ) );
if ( ( outFile = open( sTargetFileName, _O_BINARY | _O_RDWR | _O_CREAT | _O_EXCL , _S_IREAD | _S_IWRITE ) ) == -1 )
{
close(inFile);
throw ( CZipException( "unable to create target file" ) );
}
ifd=inFile; ofd=outFile;
int ret = HardWork( inFile, outFile );
close( inFile );
close( outFile );
if (ret != 0)
throw( CZipException( "problem while %s file", m_sOperation ) );
}
CZip::CZip( const char* sSourceFileName )
: CMamaZip( sSourceFileName )
{
m_sOperation = "zipping";
strcpy( ifname, m_sSourceFileName );
save_orig_name = 1;
}
CUnzip::CUnzip( const char* sSourceFileName )
: CMamaZip( sSourceFileName )
{
m_sOperation = "unzipping";
}
int CUnzip::HardWork( int inFile, int outFile )
{
return dounzip( inFile, outFile );
}
int CZip::HardWork( int inFile, int outFile )
{
return dozip( inFile, outFile );
}
Вывод конф. Тип этого zip-проекта - статическая библиотека (.lib)
Я построил этот проект и получил файл zipdll.lib.
А в другом проекте я установил необходимые конфигурации, такие как дополнительная библиотека
и включите заголовочный файл. Наконец-то мой код
#include "czip.h"
#pragma comment(lib, "zipdll")
.
.
.
CZip oZip(sourceFile);
oZip.SwapSize(targetFile);
Когда я строил проект, я получил эти ошибки;
1>c:\users\16481min\desktop\czip_demo\main.cpp(91): warning C4101: 'e' : unreferenced local variable
1>main.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __thiscall CMamaZip::SwapSize(char const *)" (__imp_?SwapSize@CMamaZip@@QAEXPBD@Z)
1>main.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall CZip::CZip(char const *)" (__imp_??0CZip@@QAE@PBD@Z)
1>.\Debug\test_zip.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
В чем проблема? Что мне нужно сделать? Любая помощь?
РЕДАКТИРОВАТЬ:
Основная функция:
#include "czip.h"
#include <string>
#include <tchar.h>
#include <wininet.h>
#pragma comment(lib, "wininet")
#pragma comment(lib, "zipdll")
typedef char OSC;
using namespace std;
void ZipSend(OSC *directory, OSC *ftpServerAddr, OSC *ftpUsername, OSC *ftpPassword);
int main()
{
try
{
ZipSend("C:\\Users\\16481MIN\\Desktop\\Foto","10.100.47.23","ftptestuser","abcd+1234");
}
catch( CZipException e )
{
return -1;
}
return 0;
}
void ZipSend(OSC *directory, OSC *ftpServerAddr, OSC *ftpUsername, OSC *ftpPassword)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
OSC pattern[MAX_PATH];
OSC sourceFile[MAX_PATH];
OSC targetFile[MAX_PATH];
memset(pattern, 0x00, MAX_PATH);
sprintf(pattern,"%s\\*.*", directory);
hFind = FindFirstFile(pattern, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
}
else
{
do
{
if(_tcscmp(FindFileData.cFileName, TEXT("."))==0 || _tcscmp(FindFileData.cFileName, TEXT(".."))==0)
continue;
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
}
else
{
memset(sourceFile, 0x00, sizeof(sourceFile));
memset(targetFile, 0x00, sizeof(targetFile));
string strSourceFile(FindFileData.cFileName);
int lastindex = strSourceFile.find_last_of(".");
string strTargetFile(strSourceFile.substr(0, lastindex));
sprintf(sourceFile,"%s\\%s", directory, strSourceFile.c_str());
sprintf(targetFile, "%s\\%s.zip", directory, strTargetFile.c_str());
try
{
CZip oZip(sourceFile);
oZip.SwapSize(targetFile);
}
catch( CZipException e )
{
}
try
{
OSC ftpFilePath[MAX_PATH] = "";
strcat(ftpFilePath, "/hobim/ASYADAN/");
strcat(ftpFilePath, strTargetFile.c_str());
strcat(ftpFilePath, ".zip");
}
catch(exception e)
{
}
}
}
while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
}
2 ответа
Вы пропустили экспорт как DLL из вашего заголовочного файла:
#ifndef DLL_INTERNAL
#define DLL_INTERNAL __declspec( dllimport )
#endif
укажу DLL_INTERNAL
как то, что эта библиотека захочет импортировать из другой библиотеки. Это происходит в коде клиента (одно приложение, использующее библиотеку). В код вашей библиотеки вам нужно
#ifndef DLL_INTERNAL
#define DLL_INTERNAL __declspec( dllexport )
#endif
чтобы указать эти методы будут выходить из этой библиотеки.
Но, как правило, об этом заботится инфраструктура MSVS, где приложение компилируется с определенным определением, чтобы сказать, является ли это компилируемой библиотекой (где оно должно использоваться dllexport
) или клиент (где его нужно использовать dllimport
)
Таким образом, полный макрос экспорта / импорта выглядит так:
#ifndef DLL_COMPILED
#define DLL_INTERNAL __declspec( dllexport )
else
#define DLL_INTERNAL __declspec( dllimport )
#endif
и вам нужно позаботиться о том, чтобы DLL_COMPILED
указывается на этапе компиляции (как параметр для компилятора, обычно с /DDLL_COMPILED
) библиотеки.
Линкер ищет CMamaZip::SwapSize(char const *)
вход - char const *
и в czip.h метод - SwapSize( const char *sTargetFileName )
с вводом - const char *