2012-07-25 50 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

相关问题