0

我试图从 C++ Win32 控制台应用程序的空 C dll 中调用函数 long *Test(int)。该 dll 称为 QSIWrapperUMeLt.dll。当我尝试构建控制台应用程序时,我得到以下输出:

 adding resource. type:MANIFEST, name:1, language:0x0409, flags:0x30, size:406
1>TestPlatform.obj : error LNK2019: unresolved external symbol _Test referenced in function _wmain
1>C:\Users\Deven Bryant\Desktop\temp version\TestPlatform\Debug\TestPlatform.exe : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED. 

这是我为了从我的控制台应用程序调用我的 QSIWrapperUMeLt dll 所做的;在 dll 中,我在函数定义中包含了extern "C"and__declspec(dllexport)属性。dll 和控制台应用程序都设置为为 Win32 构建。我已确保在项目设置中将 dll 设置为编译为 c 代码。在控制台应用程序中,我已经#includedQSIWrapperUMeLt.h文件并更改__declspec(dllexport)__declspec(dllimport)使用预处理器指令。我还使用 .dll 链接到 dll #pragma comment(lib, "DLLTutorial.lib")。QSIWrapperUMeLt 库文件、头文件和 dll 位于我的控制台应用程序的项目文件夹中。

下面我提供了 dll 的头文件、控制台应用程序 cpp 文件以及在 QSIWrapperUMeLt.dll 上运行时由 dumpbin 检测到的符号表和导出函数。

另外,我尝试了显式链接路由,但是当我调用加载库时,它返回一个空指针。

关于我做错了什么的任何想法将不胜感激。

QSIWrapperUMELt.h

#include <Windows.h>
//#pragma comment(lib, "DLLTutorial.lib")

#ifdef EXPORT
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport);
#endif

#define BOOL int
#define TRUE 1
#define FLSE 0

typedef enum
{
    initialize = 0,
    setup,
    capture,
    temperature,
    close,
    getimagedata
} CallStates;

typedef struct ReturnedValues
{
    BOOL initialized, imagereadyflag, exposuredone;
    long** imagedata;
    double Temperature;
}ReturnedValues;

typedef struct CameraData
{
    short Mode;
    short Binning;
    int Exposure;
    int Top;
    int Left;
    int Height;  //ROIH
    int Width;   //ROIW
    int CoolerSetpoint;
    int Temperature;
}CameraData;

typedef void (*callFunction)(CameraData camdata, ReturnedValues *retvals);


DECLSPEC ReturnedValues *retvals;
callFunction pcallFunction;
HINSTANCE hlib;
CameraData camdata;

#ifdef __cplusplus 
extern "C"
{
#endif
DECLSPEC ReturnedValues entryPoint();
DECLSPEC long *Test(int length);
#ifdef __cplusplus
}
#endif

TestPlatform.cpp(控制台应用程序) 我只是想从中调用 Test()

#include "stdafx.h"
#include <Windows.h>
#include <iostream> 
#include <conio.h>
#include <strsafe.h>
#define IMPORT
//#define EXPLICIT
using namespace std;
#ifndef EXPLICIT
#include "QSIWrapperUMeLt.h"
//#include "QSIAccessor.h"
#pragma comment(lib, "QSIWrapperUMeLt.lib")
//#pragma comment(lib, "QSIAccessorUMEmpty.lib")
#endif

#ifdef EXPLICIT
typedef long *(*Test)(int length);
HINSTANCE hinstlib;
Test pTest;
#endif

void ErrorExit(LPTSTR lpszFunction);

int _tmain(int argc, _TCHAR* argv[])
{
    int temp = 1;
    long *data;
#ifdef EXPLICIT
    hinstlib = LoadLibrary((LPCWSTR)"QSIWrapperUMeLt.dll");
    if(hinstlib)
    {
#endif
        int i;
        cout << "hinstlib was successfully initialized" << endl;
#ifdef EXPLICIT
        pTest = (Test)GetProcAddress(hinstlib, (LPCSTR)"Test");
        data = pTest(10000);
#else
        data = Test(1000);
        //callFunction(CameraData *camdata, ReturnedValues *retvals);
#endif
        for(i = 0; i < 20; i++)
        {
            cout << data[i] << endl;
        }
#ifdef EXPLICIT
    }
    else
    {
        ErrorExit(TEXT("LoadLibrary"));
    }
    FreeLibrary(hinstlib);
#endif
    getch();
    return 0;
}

void ErrorExit(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}

QSIWrapperUMeLt 符号表

            C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin>dumpbin /SYMBOLS "C:\Users\...\Desktop\temp version\C_C++libs\QSIWrapperUMeLt\Debug\QSIWrapperUMeLt.li
            b"
            Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
            Copyright (C) Microsoft Corporation.  All rights reserved.


            Dump of file C:\Users\Deven Bryant\Desktop\temp version\C_C++libs\QSIWrapperUMeLt\Debug\QSIWrapperUMeLt.lib

            File Type: LIBRARY

            COFF SYMBOL TABLE
            000 009C766F ABS    notype       Static       | @comp.id
            001 00000000 SECT2  notype       External     | __IMPORT_DESCRIPTOR_QSIWrapperUMeLt
            002 C0000040 SECT2  notype       Section      | .idata$2
            003 00000000 SECT3  notype       Static       | .idata$6
            004 C0000040 UNDEF  notype       Section      | .idata$4
            005 C0000040 UNDEF  notype       Section      | .idata$5
            006 00000000 UNDEF  notype       External     | __NULL_IMPORT_DESCRIPTOR
            007 00000000 UNDEF  notype       External     | ¦QSIWrapperUMeLt_NULL_THUNK_DATA

            String Table Size = 0x62 bytes

            COFF SYMBOL TABLE
            000 009C766F ABS    notype       Static       | @comp.id
            001 00000000 SECT2  notype       External     | __NULL_IMPORT_DESCRIPTOR

            String Table Size = 0x1D bytes

            COFF SYMBOL TABLE
            000 009C766F ABS    notype       Static       | @comp.id
            001 00000000 SECT2  notype       External     | ¦QSIWrapperUMeLt_NULL_THUNK_DATA

            String Table Size = 0x25 bytes

              Summary

                      DB .debug$S
                      14 .idata$2
                      14 .idata$3
                       4 .idata$4
                       4 .idata$5
                      14 .idata$6

QSIWrapperUMeLt 出口

            C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin>dumpbin /EXPORTS "C:\Users\...\Desktop\temp version\C_C++libs\QSIWrapperUMeLt\Debug\QSIWrapperUMeLt.dl
            l"
            Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
            Copyright (C) Microsoft Corporation.  All rights reserved.


            Dump of file C:\Users\Deven Bryant\Desktop\temp version\C_C++libs\QSIWrapperUMeLt\Debug\QSIWrapperUMeLt.dll

            File Type: DLL

              Section contains the following exports for QSIWrapperUMeLt.dll

                00000000 characteristics
                500E089F time date stamp Mon Jul 23 19:29:51 2012
                    0.00 version
                       1 ordinal base
                       3 number of functions
                       3 number of names

                ordinal hint RVA      name

                      1    0 00011127 Test = @ILT+290(_Test)
                      2    1 0001102D entryPoint = @ILT+40(_entryPoint)
                      3    2 00017580 retvals = _retvals

              Summary

                    1000 .data
                    1000 .idata
                    2000 .rdata
                    1000 .reloc
                    1000 .rsrc
                    4000 .text
                   10000 .textbss
4

1 回答 1

1

当未定义 EXPLICIT 时,我看不到您的问题的原因。但是,这是 LoadLibrary 参数中的问题:

(LPCWSTR)"QSIWrapperUMeLt.dll"

ANSI 字符串“QSIWrapperUMeLt.dll”是一个字节数组,包含一堆单字节字符,以单字节 NUL 结尾。在函数参数等表达式中使用时,表达式将转换为指向第一个字符的指针,即 char* 或 LPSTR 类型的指针。

您将指针转换为类型 LPCWSTR。但是,指针仍然指向一堆单字节字符,以单字节 NUL 结束。

因为你想要一个 Unicode 字符串,你可以这样做:

L"QSIWrapperUMeLt.dll"

或者在将来可能需要您的代码时与 ANSI 或 Unicode 兼容:

_T("QSIWrapperUMeLt.dll")
于 2012-07-26T00:40:51.183 回答