2012-07-25 98 views
0

我試圖調用函數long *從C++ Win32控制檯應用程序中的空C++ DLL中測試(int)。該DLL被稱爲QSIWrapperUMeLt.dll。當我嘗試建立控制檯應用程序,我得到以下輸出:LNK2019:從C++控制檯調用C DLL中的函數時無法解析的外部應用程序(無CLR)

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代碼。在控制檯應用程序中,我使用預處理器指令#include d​​文件並將__declspec(dllexport)更改爲__declspec(dllimport)。我也鏈接到與​​的dll。 QSIWrapperUMeLt庫文件,頭文件和dll位於我的控制檯應用程序的項目文件夾中。

Bellow我在QSIWrapperUMeLt.dll上運行時提供了dll的頭文件,控制檯應用程序cpp文件以及由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(控制檯應用程序) 我只是在試圖從這個

#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 
+0

你確實有實現你的函數'Test()'的源文件?如果沒有,那就是鏈接器找不到它的原因。 – 2012-07-25 22:26:30

+0

是的功能已經實現。它只是構建一個並返回一個指向數組的指針。問題已經解決了,謝謝你的回覆。 – Yoshimitsu 2012-07-26 01:30:34

回答

1

我沒有看到顯沒有定義時,您的問題的原因。然而,這裏是你的問題的爭論給LoadLibrary:

(LPCWSTR)"QSIWrapperUMeLt.dll" 

ANSI字符串「QSIWrapperUMeLt.dll」是一個字節數組,其中包含一串單字節字符,用單字節NUL終止。當在諸如函數參數的表達式中使用時,表達式被轉換爲指向第一個字符的指針,即char *或LPSTR類型的指針。

您投射指針鍵入LPCWSTR。但是,指針仍然指向一堆單字節字符,以單字節NUL結尾。

既然你想有一個Unicode字符串,你可以這樣做:

L"QSIWrapperUMeLt.dll" 

或與兼容ANSI或Unicode時可能會在將來需要你的代碼:

_T("QSIWrapperUMeLt.dll") 
+0

感謝您的回覆。現在一切正常。 – Yoshimitsu 2012-07-26 01:08:16

+0

Upvote提及VS/Windows的'_T'宏。當處理win32和'_UNICODE'的不確定狀態時,'_T'是一個救星。 – moshbear 2012-07-26 01:47:14

相關問題