zw_7627 发表于 2023-4-6 00:05:37

请教VS2013 引入头文件 报lnk2001求解

确定 库文件添加到工程 目录了。头文件中使用了 #define EXTERNC                extern "C"
EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd);

cpp里面调用VCI_CloseDevice就报LNK2001。

t3486784401 发表于 2023-4-6 01:23:06

链接器的命令行里,有没有加 XXXX.lib ?

zw_7627 发表于 2023-4-6 09:43:38

连接器linker,输入input,添加了xxx.lib

zw_7627 发表于 2023-4-6 09:46:12

t3486784401 发表于 2023-4-6 01:23
链接器的命令行里,有没有加 XXXX.lib ?
(引用自2楼)

加了,cpp里也加了#pragma comment(lib, "xxx.lib")。无效

t3486784401 发表于 2023-4-6 15:20:08

在 VS 的控制台里,用 dumpbin /export 指令查看下最终的 dll 文件,确认接口名称正确;
然后用 LoadLibrary 和 GetProcAddress 接口动态加载下 dll,看是否能返回有效的函数地址。

这两个确认后,基本就能排除是否是函数名的问题了。感觉像是头文件没有调用正确。

wudicgi 发表于 2023-4-6 15:23:22

修改配置时选择的平台, Debug/Release 版本和编译时选择的是否相同?
x86/x64 + Debug/Release 在项目文件里会有 4 份配置值,有时修改时容易只修改其中一部分

zw_7627 发表于 2023-4-6 23:59:46

t3486784401 发表于 2023-4-6 15:20
在 VS 的控制台里,用 dumpbin /export 指令查看下最终的 dll 文件,确认接口名称正确;
然后用 LoadLibrar ...
(引用自5楼)

Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.All rights reserved.

LINK : warning LNK4044: unrecognized option '/export'; ignored

Dump of file ControlCAN.dll

File Type: DLL

Summary

      1D5000 .data
      5000 .rdata
      3000 .reloc
      1000 .rsrc
      E000 .text

D:\>dumpbin /exports ControlCAN.dll
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.All rights reserved.


Dump of file ControlCAN.dll

File Type: DLL

Section contains the following exports for ControlCAN_l.dll

    00000000 characteristics
    63F41B14 time date stamp Tue Feb 21 09:15:00 2023
      0.00 version
         1 ordinal base
          74 number of functions
          74 number of names

    ordinal hint RVA      name

          1    0 00008970 ??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@ABV01@@Z
          2    1 00008900 ??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@XZ
          3    2 00008250 ??0CSerialPort@itas109@@QAE@ABV01@@Z
          4    3 0000AD80 ??0CSerialPort@itas109@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
          5    4 0000ACD0 ??0CSerialPort@itas109@@QAE@XZ
          6    5 00008BF0 ??1?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@UAE@XZ
          7    6 0000AE30 ??1CSerialPort@itas109@@UAE@XZ
          8    7 000081E0 ??4?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEAAV01@ABV01@@Z
          9    8 000082D0 ??4CSerialPort@itas109@@QAEAAV01@ABV01@@Z
         10    9 00010540 ??_7?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@6B@
         11    A 00010530 ??_7CSerialPort@itas109@@6B@
         12    B 0000B140 ?clearError@CSerialPort@itas109@@QAEXXZ
         13    C 0000AFA0 ?close@CSerialPort@itas109@@QAEXXZ
         14    D 00008C70 ?disconnect_all@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXXZ
         15    E 0000B240 ?getBaudRate@CSerialPort@itas109@@QBEHXZ
         16    F 0000B2C0 ?getDataBits@CSerialPort@itas109@@QBE?AW4DataBits@2@XZ
         17   10 0000B340 ?getFlowControl@CSerialPort@itas109@@QBE?AW4FlowControl@2@XZ
         18   11 0000B120 ?getLastError@CSerialPort@itas109@@QBEHXZ
         19   12 0000B280 ?getParity@CSerialPort@itas109@@QBE?AW4Parity@2@XZ
         20   13 0000B1E0 ?getPortName@CSerialPort@itas109@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
         21   14 0000B380 ?getReadBufferSize@CSerialPort@itas109@@QBE_JXZ
         22   15 0000B300 ?getStopBits@CSerialPort@itas109@@QBE?AW4StopBits@2@XZ
         23   16 0000B3E0 ?getVersion@CSerialPort@itas109@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
         24   17 0000AEC0 ?init@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HW4Parity@2@W4DataBits@2@W4StopBits@2@W4FlowControl@2@_J@Z
         25   18 0000AFC0 ?isOpened@CSerialPort@itas109@@QAE_NXZ
         26   19 0000B410 ?onReadReady@CSerialPort@itas109@@QAEXXZ
         27   1A 0000AF80 ?open@CSerialPort@itas109@@QAE_NXZ
         28   1B 0000B000 ?readAllData@CSerialPort@itas109@@QAEHPAD@Z
         29   1C 0000AFE0 ?readData@CSerialPort@itas109@@QAEHPADH@Z
         30   1D 0000B020 ?readLineData@CSerialPort@itas109@@QAEHPADH@Z
         31   1E 0000B220 ?setBaudRate@CSerialPort@itas109@@QAEXH@Z
         32   1F 0000B2A0 ?setDataBits@CSerialPort@itas109@@QAEXW4DataBits@2@@Z
         33   20 0000B0C0 ?setDebugModel@CSerialPort@itas109@@QAEX_N@Z
         34   21 0000B3A0 ?setDtr@CSerialPort@itas109@@QAEX_N@Z
         35   22 0000B320 ?setFlowControl@CSerialPort@itas109@@QAEXW4FlowControl@2@@Z
         36   23 0000B100 ?setMinByteReadNotify@CSerialPort@itas109@@QAEXI@Z
         37   24 0000AF60 ?setOperateMode@CSerialPort@itas109@@QAEXW4OperateMode@2@@Z
         38   25 0000B260 ?setParity@CSerialPort@itas109@@QAEXW4Parity@2@@Z
         39   26 0000B160 ?setPortName@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
         40   27 0000B360 ?setReadBufferSize@CSerialPort@itas109@@QAEX_J@Z
         41   28 0000B0E0 ?setReadTimeInterval@CSerialPort@itas109@@QAEXH@Z
         42   29 0000B3C0 ?setRts@CSerialPort@itas109@@QAEX_N@Z
         43   2A 0000B2E0 ?setStopBits@CSerialPort@itas109@@QAEXW4StopBits@2@@Z
         44   2B 00008B00 ?signal_connect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z
         45   2C 00008B80 ?signal_disconnect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z
         46   2D 0000B040 ?writeData@CSerialPort@itas109@@QAEHPBDH@Z
         47   2E 0000B060 ?write_N_Data@CSerialPort@itas109@@QAEHPBDH@Z
         48   2F 000060C0 ChangeKLineOfWiFiBaudRate
         49   30 00006170 GetDeviceSWandHWver
         50   31 00005B10 GetDeviceType
         51   32 00005FE0 InitKLine_Wifi
         52   33 00005FC0 KeepCommunication
         53   34 00006080 ReceiveKLine
         54   35 00005F30 SetContinueFrameIntervalTime
         55   36 00005F60 SetCtrlFrameIDandData
         56   37 00005E80 SetDevType
         57   38 00005EB0 SetFilterCANidArray
         58   39 000060F0 SetKLineFastInitTime
         59   3A 00006050 TransmitKLine
         60   3B 00005D20 VCI_ClearBuffer_l
         61   3C 00005B20 VCI_CloseDevice_l
         62   3D 00005CF0 VCI_GetReceiveNum_l
         63   3E 00005C90 VCI_GetReference_l
         64   3F 00005B50 VCI_InitCAN_l
         65   40 00005A70 VCI_OpenDevice_l
         66   41 00005BB0 VCI_ReadBoardInfo_l
         67   42 00005C60 VCI_ReadCANStatus_l
         68   43 00005C30 VCI_ReadErrInfo_l
         69   44 00005E20 VCI_Receive_l
         70   45 00005D90 VCI_ResetCAN_l
         71   46 00005CC0 VCI_SetReference_l
         72   47 00005D50 VCI_StartCAN_l
         73   48 00005DC0 VCI_Transmit_l
         74   49 00006130 closeTCPconnect

Summary

      1D5000 .data
      5000 .rdata
      3000 .reloc
      1000 .rsrc
      E000 .text


比较奇怪,头文件的函数名,怎么和这里面的函数名不一致。而且按照此VCI_CloseDevice_l()调用函数仍然报LNK2001

zw_7627 发表于 2023-4-7 00:01:41

wudicgi 发表于 2023-4-6 15:23
修改配置时选择的平台, Debug/Release 版本和编译时选择的是否相同?
x86/x64 + Debug/Release 在项目文件 ...
(引用自6楼)

我另一个工程里用的另外的LIB是正常使用的。说明配置是正常的。只是这个LIB第一次用。

zw_7627 发表于 2023-4-7 00:06:18

zw_7627 发表于 2023-4-7 00:01
我另一个工程里用的另外的LIB是正常使用的。说明配置是正常的。只是这个LIB第一次用。 ...
(引用自8楼)

LIB的:
D:\>dumpbin /exports ControlCAN.lib
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
Copyright (C) Microsoft Corporation.All rights reserved.


Dump of file ControlCAN.lib

File Type: LIBRARY

   Exports

       ordinal    name

                  ??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@ABV01@@Z (public: __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::has_slots<class sigslot::multi_threaded_local>(class sigslot::has_slots<class sigslot::multi_threaded_local> const &))
                  ??0?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAE@XZ (public: __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::has_slots<class sigslot::multi_threaded_local>(void))
                  ??0CSerialPort@itas109@@QAE@ABV01@@Z (public: __thiscall itas109::CSerialPort::CSerialPort(class itas109::CSerialPort const &))
                  ??0CSerialPort@itas109@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z (public: __thiscall itas109::CSerialPort::CSerialPort(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &))
                  ??0CSerialPort@itas109@@QAE@XZ (public: __thiscall itas109::CSerialPort::CSerialPort(void))
                  ??1?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@UAE@XZ (public: virtual __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::~has_slots<class sigslot::multi_threaded_local>(void))
                  ??1CSerialPort@itas109@@UAE@XZ (public: virtual __thiscall itas109::CSerialPort::~CSerialPort(void))
                  ??4?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEAAV01@ABV01@@Z (public: class sigslot::has_slots<class sigslot::multi_threaded_local> & __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::operator=(class sigslot::has_slots<class sigslot::multi_threaded_local> const &))
                  ??4CSerialPort@itas109@@QAEAAV01@ABV01@@Z (public: class itas109::CSerialPort & __thiscall itas109::CSerialPort::operator=(class itas109::CSerialPort const &))
                  ??_7?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@6B@ (const sigslot::has_slots<class sigslot::multi_threaded_local>::`vftable')
                  ??_7CSerialPort@itas109@@6B@ (const itas109::CSerialPort::`vftable')
                  ?clearError@CSerialPort@itas109@@QAEXXZ (public: void __thiscall itas109::CSerialPort::clearError(void))
                  ?close@CSerialPort@itas109@@QAEXXZ (public: void __thiscall itas109::CSerialPort::close(void))
                  ?disconnect_all@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXXZ (public: void __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::disconnect_all(void))
                  ?getBaudRate@CSerialPort@itas109@@QBEHXZ (public: int __thiscall itas109::CSerialPort::getBaudRate(void)const )
                  ?getDataBits@CSerialPort@itas109@@QBE?AW4DataBits@2@XZ (public: enum itas109::DataBits __thiscall itas109::CSerialPort::getDataBits(void)const )
                  ?getFlowControl@CSerialPort@itas109@@QBE?AW4FlowControl@2@XZ (public: enum itas109::FlowControl __thiscall itas109::CSerialPort::getFlowControl(void)const )
                  ?getLastError@CSerialPort@itas109@@QBEHXZ (public: int __thiscall itas109::CSerialPort::getLastError(void)const )
                  ?getParity@CSerialPort@itas109@@QBE?AW4Parity@2@XZ (public: enum itas109::Parity __thiscall itas109::CSerialPort::getParity(void)const )
                  ?getPortName@CSerialPort@itas109@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ (public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall itas109::CSerialPort::getPortName(void)const )
                  ?getReadBufferSize@CSerialPort@itas109@@QBE_JXZ (public: __int64 __thiscall itas109::CSerialPort::getReadBufferSize(void)const )
                  ?getStopBits@CSerialPort@itas109@@QBE?AW4StopBits@2@XZ (public: enum itas109::StopBits __thiscall itas109::CSerialPort::getStopBits(void)const )
                  ?getVersion@CSerialPort@itas109@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ (public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall itas109::CSerialPort::getVersion(void))
                  ?init@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HW4Parity@2@W4DataBits@2@W4StopBits@2@W4FlowControl@2@_J@Z (public: void __thiscall itas109::CSerialPort::init(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,enum itas109::Parity,enum itas109::DataBits,enum itas109::StopBits,enum itas109::FlowControl,__int64))
                  ?isOpened@CSerialPort@itas109@@QAE_NXZ (public: bool __thiscall itas109::CSerialPort::isOpened(void))
                  ?onReadReady@CSerialPort@itas109@@QAEXXZ (public: void __thiscall itas109::CSerialPort::onReadReady(void))
                  ?open@CSerialPort@itas109@@QAE_NXZ (public: bool __thiscall itas109::CSerialPort::open(void))
                  ?readAllData@CSerialPort@itas109@@QAEHPAD@Z (public: int __thiscall itas109::CSerialPort::readAllData(char *))
                  ?readData@CSerialPort@itas109@@QAEHPADH@Z (public: int __thiscall itas109::CSerialPort::readData(char *,int))
                  ?readLineData@CSerialPort@itas109@@QAEHPADH@Z (public: int __thiscall itas109::CSerialPort::readLineData(char *,int))
                  ?setBaudRate@CSerialPort@itas109@@QAEXH@Z (public: void __thiscall itas109::CSerialPort::setBaudRate(int))
                  ?setDataBits@CSerialPort@itas109@@QAEXW4DataBits@2@@Z (public: void __thiscall itas109::CSerialPort::setDataBits(enum itas109::DataBits))
                  ?setDebugModel@CSerialPort@itas109@@QAEX_N@Z (public: void __thiscall itas109::CSerialPort::setDebugModel(bool))
                  ?setDtr@CSerialPort@itas109@@QAEX_N@Z (public: void __thiscall itas109::CSerialPort::setDtr(bool))
                  ?setFlowControl@CSerialPort@itas109@@QAEXW4FlowControl@2@@Z (public: void __thiscall itas109::CSerialPort::setFlowControl(enum itas109::FlowControl))
                  ?setMinByteReadNotify@CSerialPort@itas109@@QAEXI@Z (public: void __thiscall itas109::CSerialPort::setMinByteReadNotify(unsigned int))
                  ?setOperateMode@CSerialPort@itas109@@QAEXW4OperateMode@2@@Z (public: void __thiscall itas109::CSerialPort::setOperateMode(enum itas109::OperateMode))
                  ?setParity@CSerialPort@itas109@@QAEXW4Parity@2@@Z (public: void __thiscall itas109::CSerialPort::setParity(enum itas109::Parity))
                  ?setPortName@CSerialPort@itas109@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z (public: void __thiscall itas109::CSerialPort::setPortName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >))
                  ?setReadBufferSize@CSerialPort@itas109@@QAEX_J@Z (public: void __thiscall itas109::CSerialPort::setReadBufferSize(__int64))
                  ?setReadTimeInterval@CSerialPort@itas109@@QAEXH@Z (public: void __thiscall itas109::CSerialPort::setReadTimeInterval(int))
                  ?setRts@CSerialPort@itas109@@QAEX_N@Z (public: void __thiscall itas109::CSerialPort::setRts(bool))
                  ?setStopBits@CSerialPort@itas109@@QAEXW4StopBits@2@@Z (public: void __thiscall itas109::CSerialPort::setStopBits(enum itas109::StopBits))
                  ?signal_connect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z (public: void __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::signal_connect(class sigslot::_signal_base<class sigslot::multi_threaded_local> *))
                  ?signal_disconnect@?$has_slots@Vmulti_threaded_local@sigslot@@@sigslot@@QAEXPAV?$_signal_base@Vmulti_threaded_local@sigslot@@@2@@Z (public: void __thiscall sigslot::has_slots<class sigslot::multi_threaded_local>::signal_disconnect(class sigslot::_signal_base<class sigslot::multi_threaded_local> *))
                  ?writeData@CSerialPort@itas109@@QAEHPBDH@Z (public: int __thiscall itas109::CSerialPort::writeData(char const *,int))
                  ?write_N_Data@CSerialPort@itas109@@QAEHPBDH@Z (public: int __thiscall itas109::CSerialPort::write_N_Data(char const *,int))
                  _ChangeKLineOfWiFiBaudRate
                  _GetDeviceSWandHWver
                  _GetDeviceType
                  _InitKLine_Wifi
                  _KeepCommunication
                  _ReceiveKLine
                  _SetContinueFrameIntervalTime
                  _SetCtrlFrameIDandData
                  _SetDevType
                  _SetFilterCANidArray
                  _SetKLineFastInitTime
                  _TransmitKLine
                  _VCI_ClearBuffer_l
                  _VCI_CloseDevice_l
                  _VCI_GetReceiveNum_l
                  _VCI_GetReference_l
                  _VCI_InitCAN_l
                  _VCI_OpenDevice_l
                  _VCI_ReadBoardInfo_l
                  _VCI_ReadCANStatus_l
                  _VCI_ReadErrInfo_l
                  _VCI_Receive_l
                  _VCI_ResetCAN_l
                  _VCI_SetReference_l
                  _VCI_StartCAN_l
                  _VCI_Transmit_l
                  _closeTCPconnect

Summary

          D2 .debug$S
          14 .idata$2
          14 .idata$3
         4 .idata$4
         4 .idata$5
          12 .idata$6

D:\>

wudicgi 发表于 2023-4-7 00:43:28

到底是动态库还是静态库,怎么 dumpbin 的文件一个是 .dll 一个是 .lib

符号和原始函数名不一致是因为 name mangling
https://zh.wikipedia.org/wiki/%E5%90%8D%E5%AD%97%E4%BF%AE%E9%A5%B0

zw_7627 发表于 2023-4-7 07:41:32

wudicgi 发表于 2023-4-7 00:43
到底是动态库还是静态库,怎么 dumpbin 的文件一个是 .dll 一个是 .lib

符号和原始函数名不一致是因为 nam ...
(引用自10楼)

有三个文件,.h,.lib,.dll,动态库。维基百科没梯子上不去{:sweat:}

zw_7627 发表于 2023-4-7 07:44:28

void *p=NULL;
p=LoadLibrary("XXX.dll");
返回值是0

t3486784401 发表于 2023-4-7 23:19:00

zw_7627 发表于 2023-4-7 00:06
LIB的:
D:\>dumpbin /exports ControlCAN.lib
Microsoft (R) COFF/PE Dumper Version 12.00.30501.0
(引用自9楼)

我查看了手头的一些库,的确 lib 当中的函数名应该比 dll 当中多一个前置下划线,最终调用的函数名以 dll 为准。

至于 LoadLibrary 失败的话,考虑在 Unicode 环境下(默认VS选项)使用
    ::LoadLibrary(_T("C:\\XXX\\YY.dll"));
这样的完整路径,并强制使用 Unicode 字符串

zw_7627 发表于 2023-4-8 00:11:04

t3486784401 发表于 2023-4-7 23:19
我查看了手头的一些库,的确 lib 当中的函数名应该比 dll 当中多一个前置下划线,最终调用的函数名以 dll ...
(引用自13楼)

void *p=NULL;
        p = LoadLibrary(_T("ControlCAN_l.dll"));
        DWORD error_id=GetLastError();
p值不为0了,error_id 为0,dll库成功 加载了。但是引用VCI_CloseDevice()函数还是报LNK2001

zw_7627 发表于 2023-4-8 00:33:31

zw_7627 发表于 2023-4-8 00:11
void *p=NULL;
        p = LoadLibrary(_T("ControlCAN_l.dll"));
        DWORD error_id=GetLastError();
(引用自14楼)

把头文件改成VCI_CloseDevice_l(),再引用也是一样。{:cry:}

t3486784401 发表于 2023-4-8 13:02:28

zw_7627 发表于 2023-4-8 00:11
void *p=NULL;
        p = LoadLibrary(_T("ControlCAN_l.dll"));
        DWORD error_id=GetLastError();
(引用自14楼)

LoadLibrary 之后是 GetProcAddress,这其中应该能定位到目标函数名。
然而这个过程是动态 dll 调用,与编译时静态调用完全是两个方向。

目测是头文件 / lib 有问题,实在不行就考虑动态调用吧

wudicgi 发表于 2023-4-8 18:17:53

LZ 把工程文件删一删,只留下和问题相关的东西后打个包传上来吧。
问题应该不复杂,但不了解的话,关键信息容易被漏掉,这么讨论难出结果。

zw_7627 发表于 2023-4-9 00:42:26

本帖最后由 zw_7627 于 2023-4-9 00:43 编辑

wudicgi 发表于 2023-4-8 18:17
LZ 把工程文件删一删,只留下和问题相关的东西后打个包传上来吧。
问题应该不复杂,但不了解的话,关键信息 ...
(引用自17楼)

工程上传文件限制在16M了,打包了编译文件{:handshake:}

void CTTDlg::OnBnClickedButton1()
{
        // TODO: Add your control notification handler code here
        VCI_CloseDevice_l(1,0); //编译不过
}

wudicgi 发表于 2023-4-9 06:00:08

zw_7627 发表于 2023-4-9 00:42
工程上传文件限制在16M了,打包了编译文件

void CTTDlg::OnBnClickedButton1()
(引用自18楼)

传上来的压缩包里没有 ControlCAN.h 和 ControlCAN.lib

我从这下了份 x86 的先用着,可能和你的版本不一样
https://github.com/JloveU/ControlCAN/tree/master/ControlCANx86

在把 CTTDlg::OnBnClickedButton1() 中的调用改成 VCI_CloseDevice(1,0); 之后,在 VS2017 中是能编译通过的

我还在 stdafx.h 中添加了一行 #define no_init_all deprecated 是因为 VS2017 的 bug, 你用的 VS2013 应该没这个问题
https://stackoverflow.com/questions/61485127/including-windows-h-causes-unknown-attributeno-init-all-error

我把我编译结果的二进制文件,和 ControlCAN.h/.lib 以及修改了的 2 个源文件都传上来,你可以对比看看

wudicgi 发表于 2023-4-9 11:45:49

zw_7627 发表于 2023-4-9 00:42
工程上传文件限制在16M了,打包了编译文件

void CTTDlg::OnBnClickedButton1()
(引用自18楼)

我刚注意到你的压缩包里有 123.dll/.lib/.h, 我改名成 ControlCAN.dll/.lib/.h 后又试了一下
问题和函数声明里的调用约定有关

首先有个问题,就是 ControlCAN.dll/.lib/.h 和 ControlCAN_l.dll/.lib/.h 应该是两套东西
但是我看现在的 .dll 和 .lib 里以 VCI_ 开头的函数符号都是以 _l 结尾的,但 .h 文件里的函数名结尾又没有 _l
也就是说现在这个 .h 和 .dll/.lib 文件不是一套的

我看你发的压缩包里的 .h 是这样的:
EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved);
EXTERNC DWORD __stdcall VCI_CloseDevice_l(DWORD DeviceType, DWORD DeviceInd);
EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);

应该是自己把原来的 VCI_CloseDevice 给改成 VCI_CloseDevice_l 了,单就这个函数来说,把它改成
EXTERNC DWORD __cdecl VCI_CloseDevice_l(DWORD DeviceType, DWORD DeviceInd);
链接就能成功了

你遇到的问题,首先应该是 .h 文件不对,其次是 stdcall 调用约定时 name mangling 之后的符号名是 _function@nnn 这样的
而默认的 cdecl 调用约定出来的符号名是_function 这样的,对应不上自然链接会找不到
https://www.cnblogs.com/lidabo/archive/2012/11/21/2781484.html

zw_7627 发表于 2023-4-9 22:04:13

wudicgi 发表于 2023-4-9 11:45
我刚注意到你的压缩包里有 123.dll/.lib/.h, 我改名成 ControlCAN.dll/.lib/.h 后又试了一下
问题和函数 ...
(引用自20楼)

{:victory:} 的确编译通过了,明天调试下{:handshake:} 。
页: [1]
查看完整版本: 请教VS2013 引入头文件 报lnk2001求解