Почему компоновщик VS C ++ возвращает «LNK2001: неразрешенный внешний символ» со смешанными файлами DLL вперед? - PullRequest
0 голосов
/ 01 июня 2019

Я хочу создать DLL-оболочку, потому что мне нужно отслеживать вызовы, чтобы я мог самостоятельно использовать DLL для другого проекта.У меня нет документации по завернутой DLL.Я использовал проект wrapper2.cpp Майкла Чурдакиса для создания исходного исходного кода, приведенного ниже, но у меня возникли проблемы, и я думаю, что DLL, которую я хочу обернуть, представляет собой смесь экспорта на C и C ++.

Можеткто-нибудь объяснит мне, почему первый код не связывает, а второй делает?Мои знания C ++ ограничены, но мне нужно его использовать, потому что Delphi (для моего проекта) не может обработать управляемый экспорт C ++ (afaik).

IcuSort.cpp:

#include <windows.h>
#include <tchar.h>

#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)

HINSTANCE hLThis = 0;
HINSTANCE hL = 0;
FARPROC p[13] = {0};

BOOL WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID)
    {
    if (reason == DLL_PROCESS_ATTACH)
        {
        hLThis = hInst;
        hL = LoadLibrary(_T("IcuSortOLD.DLL"));
        if (!hL) return false;
        }
    if (reason == DLL_PROCESS_DETACH)
        {
        FreeLibrary(hL);
        }

    return 1;
    }

IcuSort.def:

EXPORTS
??0ct_IcuNumber@@QAE@ABV0@@Z=IcuSortOLD.??0ct_IcuNumber@@QAE@ABV0@@Z @1
??0ct_IcuNumber@@QAE@PB_WGG@Z=IcuSortOLD.??0ct_IcuNumber@@QAE@PB_WGG@Z @2
??1ct_IcuNumber@@QAE@XZ=IcuSortOLD.??1ct_IcuNumber@@QAE@XZ @3
??4ct_IcuNumber@@QAEAAV0@ABV0@@Z=IcuSortOLD.??4ct_IcuNumber@@QAEAAV0@ABV0@@Z @4
??8ct_IcuNumber@@QAE_NABV0@@Z=IcuSortOLD.??8ct_IcuNumber@@QAE_NABV0@@Z @5
?Clear@ct_IcuNumber@@QAEXXZ=IcuSortOLD.?Clear@ct_IcuNumber@@QAEXXZ @6
?GetFormattedNumber@ct_IcuNumber@@QAEPB_WXZ=IcuSortOLD.?GetFormattedNumber@ct_IcuNumber@@QAEPB_WXZ @7
?GetOrgNumber@ct_IcuNumber@@QAEPB_WXZ=IcuSortOLD.?GetOrgNumber@ct_IcuNumber@@QAEPB_WXZ @8
?Init@ct_IcuNumber@@QAEXPB_WGG@Z=IcuSortOLD.?Init@ct_IcuNumber@@QAEXPB_WGG@Z @9
?IsSameNumber@ct_IcuNumber@@QAE_NABV1@_N@Z=IcuSortOLD.?IsSameNumber@ct_IcuNumber@@QAE_NABV1@_N@Z @10
deleteICUSortKey=IcuSortOLD.deleteICUSortKey @11
getICULastError=IcuSortOLD.getICULastError @12
getICUSortKey=IcuSortOLD.getICUSortKey @13

Командная строка:

cl.exe /EHsc /LD IcuSort.cpp /link /DEF:IcuSort.def

Это выдает эту ошибку:

IcuSort.def : error LNK2001: unresolved external symbol deleteICUSortKey
IcuSort.def : error LNK2001: unresolved external symbol getICULastError
IcuSort.def : error LNK2001: unresolved external symbol getICUSortKey
IcuSort.lib : fatal error LNK1120: 3 unresolved externals

Однако, когда я использую этот исходный код,он компилирует / связывает без ошибок, и все функции IcuSortOld.dll правильно передаются через IcuSort.dll.

IcuSort.cpp:

#include <windows.h>
#include <tchar.h>

#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)

HINSTANCE hLThis = 0;
HINSTANCE hL = 0;
FARPROC p[13] = {0};

FARPROC lpfndeleteICUSortKey;
FARPROC lpfngetICULastError;
FARPROC lpfngetICUSortKey;

typedef unsigned long int (__cdecl * pICFUNC1)(unsigned long int, unsigned long int, unsigned long int, unsigned long int);
typedef int (__cdecl * pICFUNC2)(int);
typedef int (__cdecl * pICFUNC3)();

pICFUNC2 My_deleteICUSortKey; 
pICFUNC3 My_getICULastError;
pICFUNC1 My_getICUSortKey; 

BOOL WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID)
    {
    if (reason == DLL_PROCESS_ATTACH)
        {
        hLThis = hInst;
        hL = LoadLibrary(_T("IcuSortOLD.DLL"));
        if (!hL) return false;

        // Get function pointer
        FARPROC lpfndeleteICUSortKey = GetProcAddress(HMODULE (hL),"deleteICUSortKey"); 
        FARPROC lpfngetICULastError = GetProcAddress(HMODULE (hL),"etICULastError"); 
        FARPROC lpfngetICUSortKey = GetProcAddress(HMODULE (hL),"getICUSortKey"); 
        }
    if (reason == DLL_PROCESS_DETACH)
        {
        FreeLibrary(hL);
        }

    return 1;
    }

EXTERN_DLL_EXPORT int deleteICUSortKey(int arg1) {
  return 1;
}

EXTERN_DLL_EXPORT int getICULastError() {
  return 1;
}

EXTERN_DLL_EXPORT unsigned long int getICUSortKey(unsigned long int arg1, unsigned long int arg2, unsigned long int arg3, unsigned long int arg4) {
  return 1;
}

Почему объявление этих Cфункций, заставляющих его работать, в то время как файл .DEF явно пересылает их в IcuSortOld.dll?

Спасибо!

...