打开NFC -错误LNK2019:未解析的外部符号__imp__ShellExecuteW@24
Open NFC - Error LNK2019: unresolved external symbol __imp__ShellExecuteW@24
我有一个错误,我不知道是什么问题。
我正试图为一个项目编译一个开放NFC的例子。示例为test_ndef_url。我不知道这个问题是由于编码错误还是由于windows库。
Test_ndef_url代码为:
/*
* Copyright (c) 2007-2012 Inside Secure, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*******************************************************************************
Implementation of the Example 1 for Open NFC.
*******************************************************************************/
/* Allow use of features specific to Windows XP or later. */
#ifndef _WIN32_WINNT
/* Change this to the appropriate value to target other versions of Windows. */
#define _WIN32_WINNT 0x0601
#endif
/* Suppress many files from the compilation */
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include "shellapi.h"
#include <stdio.h>
#include <stdlib.h>
#include "open_nfc.h"
#include "win32_test_core.h"
/* Type definititions */
/* ------------------ */
/* Local prototypes */
/* ---------------- */
/* Global variables */
/* ---------------- */
struct __testContext
{
char16_t* pURL;
bool_t bVirtualTag;
bool_t bReadTest;
W_HANDLE hRegistry;
} ;
struct __testContext g_testCtx = { null, W_FALSE, W_FALSE, W_NULL_HANDLE };
/* Callback function of type tWBasicGenericHandleCallbackFunction */
static void ReadMessageOnAnyTagCompletedURL(void *pCallbackParameter, W_HANDLE hMessage, W_ERROR nError)
{
if(nError == W_SUCCESS)
{
W_HANDLE hRecord = WNDEFGetRecord(hMessage, 0);
WBasicCloseHandle(hMessage);
if(WRTDIsURIRecord(hRecord))
{
char16_t aURIValue[256];
if(WRTDURIGetValue(hRecord, (char16_t*)&aURIValue, 256) == W_SUCCESS)
{
printf("The URL read in the tag is "%S"n", aURIValue);
ShellExecute(NULL, L"open", (char16_t*)aURIValue, NULL, NULL, SW_SHOWNORMAL);
}
}
else
{
printf("Error URL: Error detected in the tag message.n");
}
WBasicCloseHandle(hRecord);
}
else if(nError == W_ERROR_ITEM_NOT_FOUND)
{
printf("Error URL: This tag does not contain a message of the right type.n");
}
else if(nError == W_ERROR_TIMEOUT)
{
printf("Error URL: Lost the communication with the tag.n");
}
else
{
printf("Error URL: Error 0x%08X returned during the tag detection.n", nError);
}
printf("Present a new tag to be read or press Ctrl+C to stop the applicationn");
}
/* Callback function of type tWBasicGenericCallbackFunction */
static void WriteMessageOnAnyTagCompleted(void *pCallbackParameter, W_ERROR nError)
{
switch(nError)
{
case W_SUCCESS:
printf("The message is written in the tag.n");
break;
case W_ERROR_LOCKED_TAG:
printf("The operation failed because the tag is locked.n");
break;
case W_ERROR_TAG_FULL:
printf("The message is too large for the remaining free space in the tag.n");
break;
default:
printf("An error occured during the writing operation (code 0x%x)n", nError);
break;
}
StopApplication();
}
/* Receive the event of the virtual tag */
static void VirtualTagEventHandler(void *pCallbackParameter, uint32_t nEventCode)
{
switch(nEventCode)
{
case W_VIRTUAL_TAG_EVENT_SELECTION:
printf("The tag is selected by the reader.n");
break;
case W_VIRTUAL_TAG_EVENT_READER_LEFT:
printf("The reader left the tag without reading the content.n");
break;
case W_VIRTUAL_TAG_EVENT_READER_READ_ONLY :
printf("The reader read the tag.nPresent again a reader to read the virtual tag or press Ctrl+C to stop the applicationn");
break;
case W_VIRTUAL_TAG_EVENT_READER_WRITE:
default:
printf("This event should not occur for a read-only virtual tag.n");
break;
}
}
/**
* GetSpecificTestSyntax
*
* @return String describing the command line syntax specific to this test
**/
char16_t * GetSpecificTestSyntax( void )
{
return L"[url <URL> | virtualurl <URL>n"
L" - If the parameter is not present, the application waits to read a tag with an URL.n"
L" - If "url" is present, the application waits for a Tag to write the URL.n"
L" - If "virtualurl" is present, the application simulates a tag containing the URL.nn"
L"The following tags are supported: Type 2, Type 4-A, Type 4-B, Type 5-2K, Type 5-32K and Type 6.nn" ;
}
/**
* VerifyTestConditions
*
* @param[in] nArgc number of arguments
*
* @param[in] pArgv arguments array
*
* @return W_SUCCESS Arguments syntax is correct
* W_ERROR_xxx is syntax error is detected
**/
W_ERROR VerifyTestConditions( int32_t nArgc, char16_t* pArgv[] )
{
if(nArgc == 3)
{
if(wcscmp(pArgv[1], L"url") == 0)
{
g_testCtx.pURL = pArgv[2];
}
else if(wcscmp(pArgv[1], L"virtualurl") == 0)
{
g_testCtx.bVirtualTag = W_TRUE;
g_testCtx.pURL = pArgv[2];
}
else
{
nArgc = 0;
}
}
if((nArgc != 1) && (nArgc != 3))
{
return W_ERROR_BAD_PARAMETER;
}
g_testCtx.bReadTest = (nArgc == 1) ? W_TRUE : W_FALSE ;
return W_SUCCESS;
}
/**
* LaunchTest
*
**/
W_ERROR LaunchTest( void )
{
W_HANDLE hMessage = W_NULL_HANDLE;
if(g_testCtx.bReadTest != W_FALSE)
{
WNDEFReadMessageOnAnyTag(ReadMessageOnAnyTagCompletedURL, null, W_PRIORITY_MAXIMUM,
W_NDEF_TNF_WELL_KNOWN, L"U", &g_testCtx.hRegistry);
printf("Present the tag to be read or press Ctrl+C to stop the applicationn");
}
else
{
if(WNDEFCreateNewMessage(&hMessage) != W_SUCCESS)
{
printf("Error: Cannot create the new message.n");
goto return_function;
}
if(WRTDURIAddRecord(hMessage, g_testCtx.pURL) != W_SUCCESS)
{
printf("Error: Cannot add the URI record in the message.n");
goto return_function;
}
if(g_testCtx.bVirtualTag == W_FALSE)
{
printf("Ready to write the URL "%S"n", g_testCtx.pURL);
WNDEFWriteMessageOnAnyTag(WriteMessageOnAnyTagCompleted, null, W_PRIORITY_MAXIMUM, hMessage, W_NDEF_ACTION_BIT_ERASE | W_NDEF_ACTION_BIT_FORMAT_ALL, &g_testCtx.hRegistry);
printf("Present the tag to be written or press Ctrl+C to stop the applicationn");
}
else
{
W_ERROR nError;
W_HANDLE hVirtualTag;
static const uint8_t aPUPI[] = { 0x01, 0x02, 0x03, 0x04 };
printf("Ready to simulate a tag with the URL "%S"n", g_testCtx.pURL);
/* Create the virtual tag, the maximum length is set to the size of the message */
nError = WVirtualTagCreate(W_PROP_NFC_TAG_TYPE_4_B, aPUPI, sizeof(aPUPI),
WNDEFGetMessageLength(hMessage), &hVirtualTag);
if(nError != W_SUCCESS)
{
printf("Cannot create the virtual tagn");
}
else
{
/* Write the message in the virtual tag */
nError = WNDEFWriteMessageSync(hVirtualTag, hMessage, W_NDEF_ACTION_BIT_ERASE | W_NDEF_ACTION_BIT_LOCK | W_NDEF_ACTION_BIT_FORMAT_ALL);
if(nError != W_SUCCESS)
{
printf("Cannot write the message in the virtual tagn");
WBasicCloseHandle(hVirtualTag);
}
else
{
/* Start the tag simulation */
nError = WVirtualTagStartSync(hVirtualTag, VirtualTagEventHandler, null, W_TRUE);
if(nError != W_SUCCESS)
{
printf("Cannot activate the virtual tagn");
WBasicCloseHandle(hVirtualTag);
}
else
{
printf("Present a reader to read the virtual tag or press Ctrl+C to stop the applicationn");
}
}
}
}
}
return_function:
WBasicCloseHandle(hMessage);
/* Go pending on WaitForSingleObject (Card/Tag operation completed or Ctrl-C) */
return W_SUCCESS;
}
/**
* CloseTest
*
**/
void CloseTest( void )
{
WBasicCloseHandle( g_testCtx.hRegistry );
}
这部分代码定义为shellapi.h,其中ShellExecute为:
#include <winapifamily.h>
/*****************************************************************************
* *
* shellapi.h - SHELL.DLL functions, types, and definitions *
* *
* Copyright (c) Microsoft Corporation. All rights reserved. *
* *
*****************************************************************************/
#ifndef _INC_SHELLAPI
#define _INC_SHELLAPI
#include <SpecStrings.h>
//
// Define API decoration for direct importing of DLL references.
//
#ifndef WINSHELLAPI
#if !defined(_SHELL32_)
#define WINSHELLAPI DECLSPEC_IMPORT
#else
#define WINSHELLAPI
#endif
#endif // WINSHELLAPI
#ifndef SHSTDAPI
#if !defined(_SHELL32_)
#define SHSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE
#define SHSTDAPI_(type) EXTERN_C DECLSPEC_IMPORT type STDAPICALLTYPE
#else
#define SHSTDAPI STDAPI
#define SHSTDAPI_(type) STDAPI_(type)
#endif
#endif // SHSTDAPI
#ifndef SHDOCAPI
#if !defined(_SHDOCVW_)
#define SHDOCAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE
#define SHDOCAPI_(type) EXTERN_C DECLSPEC_IMPORT type STDAPICALLTYPE
#else
#define SHDOCAPI STDAPI
#define SHDOCAPI_(type) STDAPI_(type)
#endif
#endif // SHDOCAPI
#if !defined(_WIN64)
#include <pshpack1.h>
#endif
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
DECLARE_HANDLE(HDROP);
_Success_(return != 0)
SHSTDAPI_(UINT) DragQueryFileA(_In_ HDROP hDrop, _In_ UINT iFile, _Out_writes_opt_(cch) LPSTR lpszFile, _In_ UINT cch);
_Success_(return != 0)
SHSTDAPI_(UINT) DragQueryFileW(_In_ HDROP hDrop, _In_ UINT iFile, _Out_writes_opt_(cch) LPWSTR lpszFile, _In_ UINT cch);
#ifdef UNICODE
#define DragQueryFile DragQueryFileW
#else
#define DragQueryFile DragQueryFileA
#endif // !UNICODE
SHSTDAPI_(BOOL) DragQueryPoint(_In_ HDROP hDrop, _Out_ POINT *ppt);
SHSTDAPI_(void) DragFinish(_In_ HDROP hDrop);
SHSTDAPI_(void) DragAcceptFiles(_In_ HWND hWnd, _In_ BOOL fAccept);
SHSTDAPI_(HINSTANCE) ShellExecuteA(_In_opt_ HWND hwnd, _In_opt_ LPCSTR lpOperation, _In_ LPCSTR lpFile, _In_opt_ LPCSTR lpParameters,
_In_opt_ LPCSTR lpDirectory, _In_ INT nShowCmd);
SHSTDAPI_(HINSTANCE) ShellExecuteW(_In_opt_ HWND hwnd, _In_opt_ LPCWSTR lpOperation, _In_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpParameters,
_In_opt_ LPCWSTR lpDirectory, _In_ INT nShowCmd);
#ifdef UNICODE
#define ShellExecute ShellExecuteW
#else
#define ShellExecute ShellExecuteA
#endif // !UNICODE
_Success_(return > 32) // SE_ERR_DLLNOTFOUND
SHSTDAPI_(HINSTANCE) FindExecutableA(_In_ LPCSTR lpFile, _In_opt_ LPCSTR lpDirectory, _Out_writes_(MAX_PATH) LPSTR lpResult);
_Success_(return > 32) // SE_ERR_DLLNOTFOUND
SHSTDAPI_(HINSTANCE) FindExecutableW(_In_ LPCWSTR lpFile, _In_opt_ LPCWSTR lpDirectory, _Out_writes_(MAX_PATH) LPWSTR lpResult);
#ifdef UNICODE
#define FindExecutable FindExecutableW
#else
#define FindExecutable FindExecutableA
这告诉我错误Microsoft Visual Studio 2013是:
Warning 1 warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification File:win32_test_core.obj Project:test_ndef_url
Error 2 error LNK2019: unresolved external symbol __imp__ShellExecuteW@24 referenced in function _ReadMessageOnAnyTagCompletedURL File:win32_test_ndef_url.obj Project:test_ndef_url
Error 3 error LNK1120: 1 unresolved externals File:test_ndef_url.exe Project:test_ndef_url
我需要帮助。
您丢失了ShellExecute
函数(好的,ShellExecuteW
,但这是您现在不需要担心的细节)的实际主体(或函数主体的占位符)。头文件中的内容是声明,但是您仍然需要定义。在本例中,它位于库中。
做这些:
- 谷歌"MSDN ShellExecute"。MSDN是微软开发者网络,也是获取Windows API文档的地方。
- 第一个链接是https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx(目前;微软网站在保持链接稳定以供将来参考方面做得很糟糕。
- 这是函数的文档。向下滚动到页面底部。有一个表格列出了这个功能的"需求"。其中之一是"库",即"Shell32"。
- 你需要链接到这个库。最简单的方法,在Visual c++(你正在使用)和一个标准的Windows库(这是)是添加以下一行到你的源文件之一(可能在最顶部):
#pragma comment (lib, "Shell32")
。(注意没有分号)
就是这样。对于更大的项目,有更好的(更可伸缩、更灵活和可移植的)方法,但是对于这个小示例,您应该可以接受。
相关文章:
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 未解析的外部符号_MsiLocateComponentW@12.
- 在C++中使用 gRPC 时未解析的外部符号
- LibPrivoxy: 未解析的外部符号 __declspec(dllimport) int __stdcall Sta
- 尝试从 XamlApplication 编译 C++/WinRT 空白应用程序时,我收到未解析的外部符号 winrt_make_*
- 我收到错误LNK2001:未解析的外部符号(C++代码)
- 可视抽象类 c++(错误 LNK 2001:未解析的外部符号)
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- 当 lib 已添加到其他依赖项时,如何在 VS 中调试未解析的外部符号错误
- 仅在少数方法(静态或共享库)中解析的外部符号
- 未解析的外部符号"__declspec(dllimport)与 Spdlog c++ 库
- 函数 _main (OPENGL C++) 中引用的未解析的外部符号 ________
- 错误LNK2019未解析的外部符号"public: __thiscall SLinkList<char>::SLinkList<char>(void)"
- 使用静态 constexpr 成员的未解析外部符号
- 引入参数化构造函数后显示 LNK 2019 未解析外部符号的代码错误
- Dlib LNK2001未解析的外部符号USER_ERROR__consistent_build_configurati
- 矛盾的未解决的外部符号+未使用的库与VS2017和FFMPEG 4
- 链接器错误:切换到unicode生成给出:未解析的外部符号WinMain
- 类模板上一个特定函数的未解析外部符号
- LNK2001:未解析的外部符号public:static类std::vector