LNK2019:从C ++控制台应用程序(无CLR)调用C dll中的函数时未解析外部

时间:2012-07-25 22:10:33

标签: c++ c visual-studio-2010

我试图从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"__declspec(dllexport)属性。 dll和控制台应用程序都设置为Win32构建。我确保将dll设置为在项目设置中编译为c代码。在控制台应用中,我#includeQSIWrapperUMeLt.h个文件,并使用预处理器指令将__declspec(dllexport)更改为__declspec(dllimport)。我还使用#pragma comment(lib, "DLLTutorial.lib")链接到了dll。 QSIWrapperUMeLt库文件,头文件和dll位于我的控制台应用程序的项目文件夹中。

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

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

对于我做错的任何想法都会非常感激。

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 SYMBOL TABLES

            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 EXPORTS

            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

1 个答案:

答案 0 :(得分:1)

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

(LPCWSTR)"QSIWrapperUMeLt.dll"

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

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

由于您需要Unicode字符串,因此可以执行以下操作:

L"QSIWrapperUMeLt.dll"

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

_T("QSIWrapperUMeLt.dll")